home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / dev / gcc / gcc270_src.lha / gcc-2.7.0-amiga / config / i386 / i386.md < prev    next >
Text File  |  1995-06-15  |  156KB  |  5,773 lines

  1. ;; GCC machine description for Intel X86.
  2. ;; Copyright (C) 1988, 1994, 1995 Free Software Foundation, Inc.
  3. ;; Mostly by William Schelter.
  4.  
  5. ;; This file is part of GNU CC.
  6.  
  7. ;; GNU CC is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation; either version 2, or (at your option)
  10. ;; any later version.
  11.  
  12. ;; GNU CC is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;; GNU General Public License for more details.
  16.  
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU CC; see the file COPYING.  If not, write to
  19. ;; the Free Software Foundation, 59 Temple Place - Suite 330,
  20. ;; Boston, MA 02111-1307, USA.
  21.  
  22.  
  23. ;; The original PO technology requires these to be ordered by speed,
  24. ;; so that assigner will pick the fastest.
  25.  
  26. ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
  27.  
  28. ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
  29. ;; updates for most instructions.
  30.  
  31. ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
  32. ;; constraint letters.
  33.  
  34. ;; the special asm out single letter directives following a '%' are:
  35. ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
  36. ;;     operands[1].
  37. ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
  38. ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
  39. ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
  40. ;; 'S' Print the opcode suffix for a 32-bit float opcode.
  41. ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
  42. ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
  43. ;; 'J' Print the appropriate jump operand.
  44.  
  45. ;; 'b' Print the QImode name of the register for the indicated operand.
  46. ;;     %b0 would print %al if operands[0] is reg 0.
  47. ;; 'w' Likewise, print the HImode name of the register.
  48. ;; 'k' Likewise, print the SImode name of the register.
  49. ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
  50. ;; 'y' Print "st(0)" instead of "st" as a register.
  51.  
  52. ;; UNSPEC usage:
  53. ;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
  54. ;;    operand 0 is the memory address to scan.
  55. ;;    operand 1 is a register containing the value to scan for.  The mode
  56. ;;       of the scas opcode will be the same as the mode of this operand.
  57. ;;    operand 2 is the known alignment of operand 0.
  58. ;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
  59. ;;    operand 0 is the argument for `sin'.
  60. ;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
  61. ;;    operand 0 is the argument for `cos'.
  62.  
  63. ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
  64. ;; But restricting MEM here would mean that gcc could not remove a redundant
  65. ;; test in cases like "incl MEM / je TARGET".
  66. ;;
  67. ;; We don't want to allow a constant operand for test insns because
  68. ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
  69. ;; be folded while optimizing anyway.
  70.  
  71. ;; All test insns have expanders that save the operands away without
  72. ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
  73. ;; after the tstM or cmp) will actually emit the tstM or cmpM.
  74.  
  75. (define_insn "tstsi_1"
  76.   [(set (cc0)
  77.     (match_operand:SI 0 "nonimmediate_operand" "rm"))]
  78.   ""
  79.   "*
  80. {
  81.   if (REG_P (operands[0]))
  82.     return AS2 (test%L0,%0,%0);
  83.  
  84.   operands[1] = const0_rtx;
  85.   return AS2 (cmp%L0,%1,%0);
  86. }")
  87.  
  88. (define_expand "tstsi"
  89.   [(set (cc0)
  90.     (match_operand:SI 0 "nonimmediate_operand" ""))]
  91.   ""
  92.   "
  93. {
  94.   i386_compare_gen = gen_tstsi_1;
  95.   i386_compare_op0 = operands[0];
  96.   DONE;
  97. }")
  98.  
  99. (define_insn "tsthi_1"
  100.   [(set (cc0)
  101.     (match_operand:HI 0 "nonimmediate_operand" "rm"))]
  102.   ""
  103.   "*
  104. {
  105.   if (REG_P (operands[0]))
  106.     return AS2 (test%W0,%0,%0);
  107.  
  108.   operands[1] = const0_rtx;
  109.   return AS2 (cmp%W0,%1,%0);
  110. }")
  111.  
  112. (define_expand "tsthi"
  113.   [(set (cc0)
  114.     (match_operand:HI 0 "nonimmediate_operand" ""))]
  115.   ""
  116.   "
  117. {
  118.   i386_compare_gen = gen_tsthi_1;
  119.   i386_compare_op0 = operands[0];
  120.   DONE;
  121. }")
  122.  
  123. (define_insn "tstqi_1"
  124.   [(set (cc0)
  125.     (match_operand:QI 0 "nonimmediate_operand" "qm"))]
  126.   ""
  127.   "*
  128. {
  129.   if (REG_P (operands[0]))
  130.     return AS2 (test%B0,%0,%0);
  131.  
  132.   operands[1] = const0_rtx;
  133.   return AS2 (cmp%B0,%1,%0);
  134. }")
  135.  
  136. (define_expand "tstqi"
  137.   [(set (cc0)
  138.     (match_operand:QI 0 "nonimmediate_operand" ""))]
  139.   ""
  140.   "
  141. {
  142.   i386_compare_gen = gen_tstqi_1;
  143.   i386_compare_op0 = operands[0];
  144.   DONE;
  145. }")
  146.  
  147. (define_insn "tstsf_cc"
  148.   [(set (cc0)
  149.     (match_operand:SF 0 "register_operand" "f"))
  150.    (clobber (match_scratch:HI 1 "=a"))]
  151.   "TARGET_80387 && ! TARGET_IEEE_FP"
  152.   "*
  153. {
  154.   if (! STACK_TOP_P (operands[0]))
  155.     abort ();
  156.  
  157.   output_asm_insn (\"ftst\", operands);
  158.  
  159.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  160.     output_asm_insn (AS1 (fstp,%y0), operands);
  161.  
  162.   return output_fp_cc0_set (insn);
  163. }")
  164.  
  165. ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
  166. ;; isn't IEEE compliant.
  167.  
  168. (define_expand "tstsf"
  169.   [(parallel [(set (cc0)
  170.            (match_operand:SF 0 "register_operand" ""))
  171.           (clobber (match_scratch:HI 1 ""))])]
  172.   "TARGET_80387 && ! TARGET_IEEE_FP"
  173.   "
  174. {
  175.   i386_compare_gen = gen_tstsf_cc;
  176.   i386_compare_op0 = operands[0];
  177.   DONE;
  178. }")
  179.  
  180. (define_insn "tstdf_cc"
  181.   [(set (cc0)
  182.     (match_operand:DF 0 "register_operand" "f"))
  183.    (clobber (match_scratch:HI 1 "=a"))]
  184.   "TARGET_80387 && ! TARGET_IEEE_FP"
  185.   "*
  186. {
  187.   if (! STACK_TOP_P (operands[0]))
  188.     abort ();
  189.  
  190.   output_asm_insn (\"ftst\", operands);
  191.  
  192.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  193.     output_asm_insn (AS1 (fstp,%y0), operands);
  194.  
  195.   return output_fp_cc0_set (insn);
  196. }")
  197.  
  198. ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  199. ;; isn't IEEE compliant.
  200.  
  201. (define_expand "tstdf"
  202.   [(parallel [(set (cc0)
  203.            (match_operand:DF 0 "register_operand" ""))
  204.           (clobber (match_scratch:HI 1 ""))])]
  205.   "TARGET_80387 && ! TARGET_IEEE_FP"
  206.   "
  207. {
  208.   i386_compare_gen = gen_tstdf_cc;
  209.   i386_compare_op0 = operands[0];
  210.   DONE;
  211. }")
  212.  
  213. (define_insn "tstxf_cc"
  214.   [(set (cc0)
  215.     (match_operand:XF 0 "register_operand" "f"))
  216.    (clobber (match_scratch:HI 1 "=a"))]
  217.   "TARGET_80387 && ! TARGET_IEEE_FP"
  218.   "*
  219. {
  220.   if (! STACK_TOP_P (operands[0]))
  221.     abort ();
  222.  
  223.   output_asm_insn (\"ftst\", operands);
  224.  
  225.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  226.     output_asm_insn (AS1 (fstp,%y0), operands);
  227.  
  228.   return output_fp_cc0_set (insn);
  229. }")
  230.  
  231. ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  232. ;; isn't IEEE compliant.
  233.  
  234. (define_expand "tstxf"
  235.   [(parallel [(set (cc0)
  236.            (match_operand:XF 0 "register_operand" ""))
  237.           (clobber (match_scratch:HI 1 ""))])]
  238.   "TARGET_80387 && ! TARGET_IEEE_FP"
  239.   "
  240. {
  241.   i386_compare_gen = gen_tstxf_cc;
  242.   i386_compare_op0 = operands[0];
  243.   DONE;
  244. }")
  245.  
  246. ;;- compare instructions.  See comments above tstM patterns about
  247. ;;  expansion of these insns.
  248.  
  249. (define_insn "cmpsi_1"
  250.   [(set (cc0)
  251.     (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
  252.          (match_operand:SI 1 "general_operand" "ri,mr")))]
  253.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  254.   "*
  255. {
  256.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  257.     {
  258.       cc_status.flags |= CC_REVERSED;
  259.       return AS2 (cmp%L0,%0,%1);
  260.     }
  261.   return AS2 (cmp%L0,%1,%0);
  262. }")
  263.  
  264. (define_expand "cmpsi"
  265.   [(set (cc0)
  266.     (compare (match_operand:SI 0 "nonimmediate_operand" "")
  267.          (match_operand:SI 1 "general_operand" "")))]
  268.   ""
  269.   "
  270. {
  271.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  272.     operands[0] = force_reg (SImode, operands[0]);
  273.  
  274.   i386_compare_gen = gen_cmpsi_1;
  275.   i386_compare_op0 = operands[0];
  276.   i386_compare_op1 = operands[1];
  277.   DONE;
  278. }")
  279.  
  280. (define_insn "cmphi_1"
  281.   [(set (cc0)
  282.     (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
  283.          (match_operand:HI 1 "general_operand" "ri,mr")))]
  284.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  285.   "*
  286. {
  287.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  288.     {
  289.       cc_status.flags |= CC_REVERSED;
  290.       return AS2 (cmp%W0,%0,%1);
  291.     }
  292.   return AS2 (cmp%W0,%1,%0);
  293. }")
  294.  
  295. (define_expand "cmphi"
  296.   [(set (cc0)
  297.     (compare (match_operand:HI 0 "nonimmediate_operand" "")
  298.          (match_operand:HI 1 "general_operand" "")))]
  299.   ""
  300.   "
  301. {
  302.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  303.     operands[0] = force_reg (HImode, operands[0]);
  304.  
  305.   i386_compare_gen = gen_cmphi_1;
  306.   i386_compare_op0 = operands[0];
  307.   i386_compare_op1 = operands[1];
  308.   DONE;
  309. }")
  310.  
  311. (define_insn "cmpqi_1"
  312.   [(set (cc0)
  313.     (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
  314.          (match_operand:QI 1 "general_operand" "qm,nq")))]
  315.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  316.   "*
  317. {
  318.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  319.     {
  320.       cc_status.flags |= CC_REVERSED;
  321.       return AS2 (cmp%B0,%0,%1);
  322.     }
  323.   return AS2 (cmp%B0,%1,%0);
  324. }")
  325.  
  326. (define_expand "cmpqi"
  327.   [(set (cc0)
  328.     (compare (match_operand:QI 0 "nonimmediate_operand" "")
  329.          (match_operand:QI 1 "general_operand" "")))]
  330.   ""
  331.   "
  332. {
  333.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  334.     operands[0] = force_reg (QImode, operands[0]);
  335.  
  336.   i386_compare_gen = gen_cmpqi_1;
  337.   i386_compare_op0 = operands[0];
  338.   i386_compare_op1 = operands[1];
  339.   DONE;
  340. }")
  341.  
  342. ;; These implement float point compares.  For each of DFmode and
  343. ;; SFmode, there is the normal insn, and an insn where the second operand
  344. ;; is converted to the desired mode.
  345.  
  346. (define_insn ""
  347.   [(set (cc0)
  348.     (match_operator 2 "VOIDmode_compare_op"
  349.             [(match_operand:XF 0 "nonimmediate_operand" "f")
  350.              (match_operand:XF 1 "nonimmediate_operand" "f")]))
  351.    (clobber (match_scratch:HI 3 "=a"))]
  352.   "TARGET_80387
  353.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  354.   "* return output_float_compare (insn, operands);")
  355.  
  356. (define_insn ""
  357.   [(set (cc0)
  358.     (match_operator 2 "VOIDmode_compare_op"
  359.             [(match_operand:XF 0 "register_operand" "f")
  360.              (float:XF
  361.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  362.    (clobber (match_scratch:HI 3 "=a"))]
  363.   "TARGET_80387"
  364.   "* return output_float_compare (insn, operands);")
  365.  
  366. (define_insn ""
  367.   [(set (cc0)
  368.     (match_operator 2 "VOIDmode_compare_op"
  369.             [(float:XF
  370.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  371.              (match_operand:XF 1 "register_operand" "f")]))
  372.    (clobber (match_scratch:HI 3 "=a"))]
  373.   "TARGET_80387"
  374.   "* return output_float_compare (insn, operands);")
  375.  
  376. (define_insn ""
  377.   [(set (cc0)
  378.     (match_operator 2 "VOIDmode_compare_op"
  379.             [(match_operand:XF 0 "register_operand" "f")
  380.              (float_extend:XF
  381.               (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
  382.    (clobber (match_scratch:HI 3 "=a"))]
  383.   "TARGET_80387"
  384.   "* return output_float_compare (insn, operands);")
  385.  
  386. (define_insn ""
  387.   [(set (cc0)
  388.     (match_operator 2 "VOIDmode_compare_op"
  389.             [(match_operand:XF 0 "register_operand" "f")
  390.              (float_extend:XF
  391.               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  392.    (clobber (match_scratch:HI 3 "=a"))]
  393.   "TARGET_80387"
  394.   "* return output_float_compare (insn, operands);")
  395.  
  396. (define_insn ""
  397.   [(set (cc0)
  398.     (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
  399.             (match_operand:XF 1 "register_operand" "f")))
  400.    (clobber (match_scratch:HI 2 "=a"))]
  401.   "TARGET_80387"
  402.   "* return output_float_compare (insn, operands);")
  403.  
  404. (define_insn ""
  405.   [(set (cc0)
  406.     (match_operator 2 "VOIDmode_compare_op"
  407.             [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
  408.              (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
  409.    (clobber (match_scratch:HI 3 "=a,a"))]
  410.   "TARGET_80387
  411.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  412.   "* return output_float_compare (insn, operands);")
  413.  
  414. (define_insn ""
  415.   [(set (cc0)
  416.     (match_operator 2 "VOIDmode_compare_op"
  417.             [(match_operand:DF 0 "register_operand" "f")
  418.              (float:DF
  419.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  420.    (clobber (match_scratch:HI 3 "=a"))]
  421.   "TARGET_80387"
  422.   "* return output_float_compare (insn, operands);")
  423.  
  424. (define_insn ""
  425.   [(set (cc0)
  426.     (match_operator 2 "VOIDmode_compare_op"
  427.             [(float:DF
  428.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  429.              (match_operand:DF 1 "register_operand" "f")]))
  430.    (clobber (match_scratch:HI 3 "=a"))]
  431.   "TARGET_80387"
  432.   "* return output_float_compare (insn, operands);")
  433.  
  434. (define_insn ""
  435.   [(set (cc0)
  436.     (match_operator 2 "VOIDmode_compare_op"
  437.             [(match_operand:DF 0 "register_operand" "f")
  438.              (float_extend:DF
  439.               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  440.    (clobber (match_scratch:HI 3 "=a"))]
  441.   "TARGET_80387"
  442.   "* return output_float_compare (insn, operands);")
  443.  
  444. (define_insn ""
  445.   [(set (cc0)
  446.     (match_operator 2 "VOIDmode_compare_op"
  447.             [(float_extend:DF
  448.               (match_operand:SF 0 "nonimmediate_operand" "fm"))
  449.              (match_operand:DF 1 "register_operand" "f")]))
  450.    (clobber (match_scratch:HI 3 "=a"))]
  451.   "TARGET_80387"
  452.   "* return output_float_compare (insn, operands);")
  453.  
  454. (define_insn ""
  455.   [(set (cc0)
  456.     (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
  457.             (match_operand:DF 1 "register_operand" "f")))
  458.    (clobber (match_scratch:HI 2 "=a"))]
  459.   "TARGET_80387"
  460.   "* return output_float_compare (insn, operands);")
  461.  
  462. ;; These two insns will never be generated by combine due to the mode of
  463. ;; the COMPARE.
  464. ;(define_insn ""
  465. ;  [(set (cc0)
  466. ;    (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
  467. ;            (float_extend:DF
  468. ;             (match_operand:SF 1 "register_operand" "f"))))
  469. ;   (clobber (match_scratch:HI 2 "=a"))]
  470. ;  "TARGET_80387"
  471. ;  "* return output_float_compare (insn, operands);")
  472. ;
  473. ;(define_insn ""
  474. ;  [(set (cc0)
  475. ;    (compare:CCFPEQ (float_extend:DF
  476. ;             (match_operand:SF 0 "register_operand" "f"))
  477. ;            (match_operand:DF 1 "register_operand" "f")))
  478. ;   (clobber (match_scratch:HI 2 "=a"))]
  479. ;  "TARGET_80387"
  480. ;  "* return output_float_compare (insn, operands);")
  481.  
  482. (define_insn "cmpsf_cc_1"
  483.   [(set (cc0)
  484.     (match_operator 2 "VOIDmode_compare_op"
  485.             [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
  486.              (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
  487.    (clobber (match_scratch:HI 3 "=a,a"))]
  488.   "TARGET_80387
  489.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  490.   "* return output_float_compare (insn, operands);")
  491.  
  492. (define_insn ""
  493.   [(set (cc0)
  494.     (match_operator 2 "VOIDmode_compare_op"
  495.             [(match_operand:SF 0 "register_operand" "f")
  496.              (float:SF
  497.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  498.    (clobber (match_scratch:HI 3 "=a"))]
  499.   "TARGET_80387"
  500.   "* return output_float_compare (insn, operands);")
  501.  
  502. (define_insn ""
  503.   [(set (cc0)
  504.     (match_operator 2 "VOIDmode_compare_op"
  505.             [(float:SF
  506.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  507.              (match_operand:SF 1 "register_operand" "f")]))
  508.    (clobber (match_scratch:HI 3 "=a"))]
  509.   "TARGET_80387"
  510.   "* return output_float_compare (insn, operands);")
  511.  
  512. (define_insn ""
  513.   [(set (cc0)
  514.     (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
  515.             (match_operand:SF 1 "register_operand" "f")))
  516.    (clobber (match_scratch:HI 2 "=a"))]
  517.   "TARGET_80387"
  518.   "* return output_float_compare (insn, operands);")
  519.  
  520. (define_expand "cmpxf"
  521.   [(set (cc0)
  522.     (compare (match_operand:XF 0 "register_operand" "")
  523.          (match_operand:XF 1 "nonimmediate_operand" "")))]
  524.   "TARGET_80387"
  525.   "
  526. {
  527.   i386_compare_gen = gen_cmpxf_cc;
  528.   i386_compare_gen_eq = gen_cmpxf_ccfpeq;
  529.   i386_compare_op0 = operands[0];
  530.   i386_compare_op1 = operands[1];
  531.   DONE;
  532. }")
  533.  
  534. (define_expand "cmpdf"
  535.   [(set (cc0)
  536.     (compare (match_operand:DF 0 "register_operand" "")
  537.          (match_operand:DF 1 "nonimmediate_operand" "")))]
  538.   "TARGET_80387"
  539.   "
  540. {
  541.   i386_compare_gen = gen_cmpdf_cc;
  542.   i386_compare_gen_eq = gen_cmpdf_ccfpeq;
  543.   i386_compare_op0 = operands[0];
  544.   i386_compare_op1 = operands[1];
  545.   DONE;
  546. }")
  547.  
  548. (define_expand "cmpsf"
  549.   [(set (cc0)
  550.     (compare (match_operand:SF 0 "register_operand" "")
  551.          (match_operand:SF 1 "nonimmediate_operand" "")))]
  552.   "TARGET_80387"
  553.   "
  554. {
  555.   i386_compare_gen = gen_cmpsf_cc;
  556.   i386_compare_gen_eq = gen_cmpsf_ccfpeq;
  557.   i386_compare_op0 = operands[0];
  558.   i386_compare_op1 = operands[1];
  559.   DONE;
  560. }")
  561.  
  562. (define_expand "cmpxf_cc"
  563.   [(parallel [(set (cc0)
  564.            (compare (match_operand:XF 0 "register_operand" "")
  565.                 (match_operand:XF 1 "register_operand" "")))
  566.           (clobber (match_scratch:HI 2 ""))])]
  567.   "TARGET_80387"
  568.   "")
  569.  
  570. (define_expand "cmpxf_ccfpeq"
  571.   [(parallel [(set (cc0)
  572.            (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
  573.                    (match_operand:XF 1 "register_operand" "")))
  574.           (clobber (match_scratch:HI 2 ""))])]
  575.   "TARGET_80387"
  576.   "
  577. {
  578.   if (! register_operand (operands[1], XFmode))
  579.     operands[1] = copy_to_mode_reg (XFmode, operands[1]);
  580. }")
  581.  
  582. (define_expand "cmpdf_cc"
  583.   [(parallel [(set (cc0)
  584.            (compare (match_operand:DF 0 "register_operand" "")
  585.                 (match_operand:DF 1 "register_operand" "")))
  586.           (clobber (match_scratch:HI 2 ""))])]
  587.   "TARGET_80387"
  588.   "")
  589.  
  590. (define_expand "cmpdf_ccfpeq"
  591.   [(parallel [(set (cc0)
  592.            (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
  593.                    (match_operand:DF 1 "register_operand" "")))
  594.           (clobber (match_scratch:HI 2 ""))])]
  595.   "TARGET_80387"
  596.   "
  597. {
  598.   if (! register_operand (operands[1], DFmode))
  599.     operands[1] = copy_to_mode_reg (DFmode, operands[1]);
  600. }")
  601.  
  602. (define_expand "cmpsf_cc"
  603.   [(parallel [(set (cc0)
  604.            (compare (match_operand:SF 0 "register_operand" "")
  605.                 (match_operand:SF 1 "register_operand" "")))
  606.           (clobber (match_scratch:HI 2 ""))])]
  607.   "TARGET_80387"
  608.   "")
  609.  
  610. (define_expand "cmpsf_ccfpeq"
  611.   [(parallel [(set (cc0)
  612.            (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
  613.                    (match_operand:SF 1 "register_operand" "")))
  614.           (clobber (match_scratch:HI 2 ""))])]
  615.   "TARGET_80387"
  616.   "
  617. {
  618.   if (! register_operand (operands[1], SFmode))
  619.     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
  620. }")
  621.  
  622. ;; logical compare
  623.  
  624. (define_insn ""
  625.   [(set (cc0)
  626.     (and:SI (match_operand:SI 0 "general_operand" "%ro")
  627.         (match_operand:SI 1 "general_operand" "ri")))]
  628.   ""
  629.   "*
  630. {
  631.   /* For small integers, we may actually use testb. */
  632.   if (GET_CODE (operands[1]) == CONST_INT
  633.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
  634.       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
  635.     {
  636.       /* We may set the sign bit spuriously.  */
  637.  
  638.       if ((INTVAL (operands[1]) & ~0xff) == 0)
  639.         {
  640.       cc_status.flags |= CC_NOT_NEGATIVE;
  641.       return AS2 (test%B0,%1,%b0);
  642.     }
  643.  
  644.       if ((INTVAL (operands[1]) & ~0xff00) == 0)
  645.         {
  646.       cc_status.flags |= CC_NOT_NEGATIVE;
  647.       operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
  648.  
  649.       if (QI_REG_P (operands[0]))
  650.         return AS2 (test%B0,%1,%h0);
  651.       else
  652.         {
  653.           operands[0] = adj_offsettable_operand (operands[0], 1);
  654.           return AS2 (test%B0,%1,%b0);
  655.         }
  656.     }
  657.  
  658.       if (GET_CODE (operands[0]) == MEM
  659.       && (INTVAL (operands[1]) & ~0xff0000) == 0)
  660.         {
  661.       cc_status.flags |= CC_NOT_NEGATIVE;
  662.       operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
  663.       operands[0] = adj_offsettable_operand (operands[0], 2);
  664.       return AS2 (test%B0,%1,%b0);
  665.     }
  666.  
  667.       if (GET_CODE (operands[0]) == MEM
  668.       && (INTVAL (operands[1]) & ~0xff000000) == 0)
  669.         {
  670.       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
  671.       operands[0] = adj_offsettable_operand (operands[0], 3);
  672.       return AS2 (test%B0,%1,%b0);
  673.     }
  674.     }
  675.  
  676.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  677.     return AS2 (test%L0,%1,%0);
  678.  
  679.   return AS2 (test%L1,%0,%1);
  680. }")
  681.  
  682. (define_insn ""
  683.   [(set (cc0)
  684.     (and:HI (match_operand:HI 0 "general_operand" "%ro")
  685.         (match_operand:HI 1 "general_operand" "ri")))]
  686.   ""
  687.   "*
  688. {
  689.   if (GET_CODE (operands[1]) == CONST_INT
  690.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
  691.       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
  692.     {
  693.       if ((INTVAL (operands[1]) & 0xff00) == 0)
  694.     {
  695.       /* ??? This might not be necessary. */
  696.       if (INTVAL (operands[1]) & 0xffff0000)
  697.         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
  698.  
  699.       /* We may set the sign bit spuriously.  */
  700.       cc_status.flags |= CC_NOT_NEGATIVE;
  701.       return AS2 (test%B0,%1,%b0);
  702.     }
  703.  
  704.       if ((INTVAL (operands[1]) & 0xff) == 0)
  705.         {
  706.       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
  707.  
  708.       if (QI_REG_P (operands[0]))
  709.         return AS2 (test%B0,%1,%h0);
  710.       else
  711.         {
  712.           operands[0] = adj_offsettable_operand (operands[0], 1);
  713.           return AS2 (test%B0,%1,%b0);
  714.         }
  715.     }
  716.     }
  717.  
  718.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  719.     return AS2 (test%W0,%1,%0);
  720.  
  721.   return AS2 (test%W1,%0,%1);
  722. }")
  723.  
  724. (define_insn ""
  725.   [(set (cc0)
  726.     (and:QI (match_operand:QI 0 "general_operand" "%qm")
  727.         (match_operand:QI 1 "general_operand" "qi")))]
  728.   ""
  729.   "*
  730. {
  731.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  732.     return AS2 (test%B0,%1,%0);
  733.  
  734.   return AS2 (test%B1,%0,%1);
  735. }")
  736.  
  737. ;; move instructions.
  738. ;; There is one for each machine mode,
  739. ;; and each is preceded by a corresponding push-insn pattern
  740. ;; (since pushes are not general_operands on the 386).
  741.  
  742. (define_insn ""
  743.   [(set (match_operand:SI 0 "push_operand" "=<")
  744.     (match_operand:SI 1 "general_operand" "g"))]
  745.   "TARGET_386"
  746.   "push%L0 %1")
  747.  
  748. ;; On a 486, it is faster to move MEM to a REG and then push, rather than
  749. ;; push MEM directly.
  750.  
  751. (define_insn ""
  752.   [(set (match_operand:SI 0 "push_operand" "=<")
  753.     (match_operand:SI 1 "nonmemory_operand" "ri"))]
  754.   "!TARGET_386 && TARGET_MOVE"
  755.   "push%L0 %1")
  756.  
  757. (define_insn ""
  758.   [(set (match_operand:SI 0 "push_operand" "=<")
  759.     (match_operand:SI 1 "general_operand" "ri"))]
  760.   "!TARGET_386 && !TARGET_MOVE"
  761.   "push%L0 %1")
  762.  
  763. ;; General case of fullword move.
  764.  
  765. ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
  766. ;; move to get the address of the symbolic object from the GOT.
  767.  
  768. (define_expand "movsi"
  769.   [(set (match_operand:SI 0 "general_operand" "")
  770.     (match_operand:SI 1 "general_operand" ""))]
  771.   ""
  772.   "
  773. {
  774.   extern int flag_pic;
  775.  
  776.   if (flag_pic && SYMBOLIC_CONST (operands[1]))
  777.     emit_pic_move (operands, SImode);
  778.  
  779.   /* Don't generate memory->memory moves, go through a register */
  780.   else if (TARGET_MOVE
  781.        && (reload_in_progress | reload_completed) == 0
  782.        && GET_CODE (operands[0]) == MEM
  783.        && GET_CODE (operands[1]) == MEM)
  784.     {
  785.       operands[1] = force_reg (SImode, operands[1]);
  786.     }
  787. }")
  788.  
  789. ;; On i486, incl reg is faster than movl $1,reg.
  790.  
  791. (define_insn ""
  792.   [(set (match_operand:SI 0 "general_operand" "=g,r")
  793.     (match_operand:SI 1 "general_operand" "ri,m"))]
  794.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  795.   "*
  796. {
  797.   rtx link;
  798.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  799.     return AS2 (xor%L0,%0,%0);
  800.  
  801.   if (operands[1] == const1_rtx
  802.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  803.       /* Make sure the insn that stored the 0 is still present.  */
  804.       && ! INSN_DELETED_P (XEXP (link, 0))
  805.       && GET_CODE (XEXP (link, 0)) != NOTE
  806.       /* Make sure cross jumping didn't happen here.  */
  807.       && no_labels_between_p (XEXP (link, 0), insn)
  808.       /* Make sure the reg hasn't been clobbered.  */
  809.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  810.     /* Fastest way to change a 0 to a 1.  */
  811.     return AS1 (inc%L0,%0);
  812.  
  813.   if (flag_pic && SYMBOLIC_CONST (operands[1]))
  814.     return AS2 (lea%L0,%a1,%0);
  815.  
  816.   return AS2 (mov%L0,%1,%0);
  817. }")
  818.  
  819. (define_insn ""
  820.   [(set (match_operand:HI 0 "push_operand" "=<")
  821.     (match_operand:HI 1 "general_operand" "g"))]
  822.   "TARGET_386"
  823.   "push%W0 %1")
  824.  
  825. (define_insn ""
  826.   [(set (match_operand:HI 0 "push_operand" "=<")
  827.     (match_operand:HI 1 "nonmemory_operand" "ri"))]
  828.   "!TARGET_386 && TARGET_MOVE"
  829.   "push%W0 %1")
  830.  
  831. (define_insn ""
  832.   [(set (match_operand:HI 0 "push_operand" "=<")
  833.     (match_operand:HI 1 "general_operand" "ri"))]
  834.   "!TARGET_386 && !TARGET_MOVE"
  835.   "push%W0 %1")
  836.  
  837. ;; On i486, an incl and movl are both faster than incw and movw.
  838.  
  839. (define_expand "movhi"
  840.   [(set (match_operand:HI 0 "general_operand" "")
  841.     (match_operand:HI 1 "general_operand" ""))]
  842.   ""
  843.   "
  844. {
  845.   /* Don't generate memory->memory moves, go through a register */
  846.   if (TARGET_MOVE
  847.       && (reload_in_progress | reload_completed) == 0
  848.       && GET_CODE (operands[0]) == MEM
  849.       && GET_CODE (operands[1]) == MEM)
  850.     {
  851.       operands[1] = force_reg (HImode, operands[1]);
  852.     }
  853. }")
  854.  
  855. (define_insn ""
  856.   [(set (match_operand:HI 0 "general_operand" "=g,r")
  857.     (match_operand:HI 1 "general_operand" "ri,m"))]
  858.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  859.   "*
  860. {
  861.   rtx link;
  862.   if (REG_P (operands[0]) && operands[1] == const0_rtx)
  863.     return AS2 (xor%L0,%k0,%k0);
  864.  
  865.   if (REG_P (operands[0]) && operands[1] == const1_rtx 
  866.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  867.       /* Make sure the insn that stored the 0 is still present.  */
  868.       && ! INSN_DELETED_P (XEXP (link, 0))
  869.       && GET_CODE (XEXP (link, 0)) != NOTE
  870.       /* Make sure cross jumping didn't happen here.  */
  871.       && no_labels_between_p (XEXP (link, 0), insn)
  872.       /* Make sure the reg hasn't been clobbered.  */
  873.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  874.     /* Fastest way to change a 0 to a 1.  */
  875.     return AS1 (inc%L0,%k0);
  876.  
  877.   if (REG_P (operands[0]))
  878.     {
  879.       if (REG_P (operands[1]))
  880.     return AS2 (mov%L0,%k1,%k0);
  881.       else if (CONSTANT_P (operands[1]))
  882.     return AS2 (mov%L0,%1,%k0);
  883.     }
  884.  
  885.   return AS2 (mov%W0,%1,%0);
  886. }")
  887.  
  888. (define_expand "movstricthi"
  889.   [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
  890.     (match_operand:HI 1 "general_operand" ""))]
  891.   ""
  892.   "
  893. {
  894.   /* Don't generate memory->memory moves, go through a register */
  895.   if (TARGET_MOVE
  896.       && (reload_in_progress | reload_completed) == 0
  897.       && GET_CODE (operands[0]) == MEM
  898.       && GET_CODE (operands[1]) == MEM)
  899.     {
  900.       operands[1] = force_reg (HImode, operands[1]);
  901.     }
  902. }")
  903.  
  904. (define_insn ""
  905.   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
  906.     (match_operand:HI 1 "general_operand" "ri,m"))]
  907.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  908.   "*
  909. {
  910.   rtx link;
  911.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  912.     return AS2 (xor%W0,%0,%0);
  913.  
  914.   if (operands[1] == const1_rtx
  915.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  916.       /* Make sure the insn that stored the 0 is still present.  */
  917.       && ! INSN_DELETED_P (XEXP (link, 0))
  918.       && GET_CODE (XEXP (link, 0)) != NOTE
  919.       /* Make sure cross jumping didn't happen here.  */
  920.       && no_labels_between_p (XEXP (link, 0), insn)
  921.       /* Make sure the reg hasn't been clobbered.  */
  922.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  923.     /* Fastest way to change a 0 to a 1.  */
  924.     return AS1 (inc%W0,%0);
  925.  
  926.   return AS2 (mov%W0,%1,%0);
  927. }")
  928.  
  929. ;; emit_push_insn when it calls move_by_pieces
  930. ;; requires an insn to "push a byte".
  931. ;; But actually we use pushw, which has the effect of rounding
  932. ;; the amount pushed up to a halfword.
  933. (define_insn ""
  934.   [(set (match_operand:QI 0 "push_operand" "=<")
  935.     (match_operand:QI 1 "immediate_operand" "n"))]
  936.   ""
  937.   "* return AS1 (push%W0,%1);")
  938.  
  939. (define_insn ""
  940.   [(set (match_operand:QI 0 "push_operand" "=<")
  941.     (match_operand:QI 1 "nonimmediate_operand" "q"))]
  942.   "!TARGET_MOVE"
  943.   "*
  944. {
  945.   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  946.   return AS1 (push%W0,%1);
  947. }")
  948.  
  949. (define_insn ""
  950.   [(set (match_operand:QI 0 "push_operand" "=<")
  951.     (match_operand:QI 1 "register_operand" "q"))]
  952.   "TARGET_MOVE"
  953.   "*
  954. {
  955.   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  956.   return AS1 (push%W0,%1);
  957. }")
  958.  
  959. ;; On i486, incb reg is faster than movb $1,reg.
  960.  
  961. ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
  962. ;; or writes %ah, %bh, %ch, %dh.
  963.  
  964. (define_expand "movqi"
  965.   [(set (match_operand:QI 0 "general_operand" "")
  966.     (match_operand:QI 1 "general_operand" ""))]
  967.   ""
  968.   "
  969. {
  970.   /* Don't generate memory->memory moves, go through a register */
  971.   if (TARGET_MOVE
  972.       && (reload_in_progress | reload_completed) == 0
  973.       && GET_CODE (operands[0]) == MEM
  974.       && GET_CODE (operands[1]) == MEM)
  975.     {
  976.       operands[1] = force_reg (QImode, operands[1]);
  977.     }
  978. }")
  979.  
  980. (define_insn ""
  981.   [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
  982.     (match_operand:QI 1 "general_operand" "*g,q,qn"))]
  983.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  984.   "*
  985. {
  986.   rtx link;
  987.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  988.     return AS2 (xor%B0,%0,%0);
  989.  
  990.   if (operands[1] == const1_rtx
  991.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  992.       /* Make sure the insn that stored the 0 is still present.  */
  993.       && ! INSN_DELETED_P (XEXP (link, 0))
  994.       && GET_CODE (XEXP (link, 0)) != NOTE
  995.       /* Make sure cross jumping didn't happen here.  */
  996.       && no_labels_between_p (XEXP (link, 0), insn)
  997.       /* Make sure the reg hasn't been clobbered.  */
  998.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  999.     /* Fastest way to change a 0 to a 1.  */
  1000.     return AS1 (inc%B0,%0);
  1001.  
  1002.   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
  1003.   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
  1004.     return (AS2 (mov%L0,%k1,%k0));
  1005.  
  1006.   return (AS2 (mov%B0,%1,%0));
  1007. }")
  1008.  
  1009. ;; If it becomes necessary to support movstrictqi into %esi or %edi,
  1010. ;; use the insn sequence:
  1011. ;;
  1012. ;;    shrdl $8,srcreg,dstreg
  1013. ;;    rorl $24,dstreg
  1014. ;;
  1015. ;; If operands[1] is a constant, then an andl/orl sequence would be
  1016. ;; faster.
  1017.  
  1018. (define_expand "movstrictqi"
  1019.   [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
  1020.     (match_operand:QI 1 "general_operand" ""))]
  1021.   ""
  1022.   "
  1023. {
  1024.   /* Don't generate memory->memory moves, go through a register */
  1025.   if (TARGET_MOVE
  1026.       && (reload_in_progress | reload_completed) == 0
  1027.       && GET_CODE (operands[0]) == MEM
  1028.       && GET_CODE (operands[1]) == MEM)
  1029.     {
  1030.       operands[1] = force_reg (QImode, operands[1]);
  1031.     }
  1032. }")
  1033.  
  1034. (define_insn ""
  1035.   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
  1036.     (match_operand:QI 1 "general_operand" "*qn,m"))]
  1037.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  1038.   "*
  1039. {
  1040.   rtx link;
  1041.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  1042.     return AS2 (xor%B0,%0,%0);
  1043.  
  1044.   if (operands[1] == const1_rtx
  1045.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  1046.       /* Make sure the insn that stored the 0 is still present.  */
  1047.       && ! INSN_DELETED_P (XEXP (link, 0))
  1048.       && GET_CODE (XEXP (link, 0)) != NOTE
  1049.       /* Make sure cross jumping didn't happen here.  */
  1050.       && no_labels_between_p (XEXP (link, 0), insn)
  1051.       /* Make sure the reg hasn't been clobbered.  */
  1052.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  1053.     /* Fastest way to change a 0 to a 1.  */
  1054.     return AS1 (inc%B0,%0);
  1055.  
  1056.   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
  1057.   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
  1058.     {
  1059.       abort ();
  1060.       return (AS2 (mov%L0,%k1,%k0));
  1061.     }
  1062.  
  1063.   return AS2 (mov%B0,%1,%0);
  1064. }")
  1065.  
  1066. (define_expand "movsf"
  1067.   [(set (match_operand:SF 0 "general_operand" "")
  1068.     (match_operand:SF 1 "general_operand" ""))]
  1069.   ""
  1070.   "
  1071. {
  1072.   /* Special case memory->memory moves and pushes */
  1073.   if (TARGET_MOVE
  1074.       && (reload_in_progress | reload_completed) == 0
  1075.       && GET_CODE (operands[0]) == MEM
  1076.       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
  1077.     {
  1078.       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
  1079.                         ? gen_movsf_push
  1080.                         : gen_movsf_mem;
  1081.  
  1082.       emit_insn ((*genfunc) (operands[0], operands[1]));
  1083.       DONE;
  1084.     }
  1085.  
  1086.   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  1087.      indicate we need the pic register loaded.  This could be optimized into stores
  1088.      of constants if the target eventually moves to memory, but better safe than
  1089.      sorry.  */
  1090.   if (flag_pic
  1091.       && GET_CODE (operands[0]) != MEM
  1092.       && GET_CODE (operands[1]) == CONST_DOUBLE
  1093.       && !standard_80387_constant_p (operands[1]))
  1094.     {
  1095.       current_function_uses_pic_offset_table = 1;
  1096.     }
  1097. }")
  1098.  
  1099. (define_insn "movsf_push_nomove"
  1100.   [(set (match_operand:SF 0 "push_operand" "=<,<")
  1101.     (match_operand:SF 1 "general_operand" "gF,f"))]
  1102.   "!TARGET_MOVE"
  1103.   "*
  1104. {
  1105.   if (STACK_REG_P (operands[1]))
  1106.     {
  1107.       rtx xops[3];
  1108.  
  1109.       if (! STACK_TOP_P (operands[1]))
  1110.         abort ();
  1111.  
  1112.       xops[0] = AT_SP (SFmode);
  1113.       xops[1] = GEN_INT (4);
  1114.       xops[2] = stack_pointer_rtx;
  1115.  
  1116.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1117.  
  1118.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1119.         output_asm_insn (AS1 (fstp%S0,%0), xops);
  1120.       else
  1121.         output_asm_insn (AS1 (fst%S0,%0), xops);
  1122.       RET;
  1123.     }
  1124.   return AS1 (push%L1,%1);
  1125. }")
  1126.  
  1127. (define_insn "movsf_push"
  1128.   [(set (match_operand:SF 0 "push_operand" "=<,<,<,<")
  1129.     (match_operand:SF 1 "general_operand" "rF,f,m,m"))
  1130.    (clobber (match_scratch:SI 2 "=X,X,r,X"))]
  1131.   ""
  1132.   "*
  1133. {
  1134.   if (STACK_REG_P (operands[1]))
  1135.     {
  1136.       rtx xops[3];
  1137.  
  1138.       if (! STACK_TOP_P (operands[1]))
  1139.         abort ();
  1140.  
  1141.       xops[0] = AT_SP (SFmode);
  1142.       xops[1] = GEN_INT (4);
  1143.       xops[2] = stack_pointer_rtx;
  1144.  
  1145.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1146.  
  1147.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1148.         output_asm_insn (AS1 (fstp%S0,%0), xops);
  1149.       else
  1150.         output_asm_insn (AS1 (fst%S0,%0), xops);
  1151.       RET;
  1152.     }
  1153.  
  1154.   else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG)
  1155.     return AS1 (push%L1,%1);
  1156.  
  1157.   else
  1158.     {
  1159.       output_asm_insn (AS2 (mov%L2,%1,%2), operands);
  1160.       return AS1 (push%L2,%2);
  1161.     }
  1162. }")
  1163.  
  1164. ;; Special memory<->memory pattern that combine will recreate from the
  1165. ;; moves to pseudos.
  1166. (define_insn "movsf_mem"
  1167.   [(set (match_operand:SF 0 "memory_operand" "=m")
  1168.     (match_operand:SF 1 "memory_operand" "m"))
  1169.    (clobber (match_scratch:SI 2 "=&r"))]
  1170.   ""
  1171.   "*
  1172. {
  1173.   output_asm_insn (AS2 (mov%L2,%1,%2), operands);
  1174.   return AS2 (mov%L0,%2,%0);
  1175. }")
  1176.  
  1177. ;; For the purposes of regclass, prefer FLOAT_REGS.
  1178. (define_insn "movsf_normal"
  1179.   [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  1180.     (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  1181.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  1182.   "*
  1183. {
  1184.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1185.  
  1186.   /* First handle a `pop' insn or a `fld %st(0)' */
  1187.  
  1188.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1189.     {
  1190.       if (stack_top_dies)
  1191.     return AS1 (fstp,%y0);
  1192.       else
  1193.         return AS1 (fld,%y0);
  1194.     }
  1195.  
  1196.   /* Handle a transfer between the 387 and a 386 register */
  1197.  
  1198.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1199.     {
  1200.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1201.       RET;
  1202.     }
  1203.  
  1204.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1205.     {
  1206.       output_to_reg (operands[0], stack_top_dies);
  1207.       RET;
  1208.     }
  1209.  
  1210.   /* Handle other kinds of writes from the 387 */
  1211.  
  1212.   if (STACK_TOP_P (operands[1]))
  1213.     {
  1214.       if (stack_top_dies)
  1215.     return AS1 (fstp%z0,%y0);
  1216.       else
  1217.         return AS1 (fst%z0,%y0);
  1218.     }
  1219.  
  1220.   /* Handle other kinds of reads to the 387 */
  1221.  
  1222.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1223.     return output_move_const_single (operands);
  1224.  
  1225.   if (STACK_TOP_P (operands[0]))
  1226.     return AS1 (fld%z1,%y1);
  1227.  
  1228.   /* Handle all SFmode moves not involving the 387 */
  1229.  
  1230.   return singlemove_string (operands);
  1231. }")
  1232.  
  1233. (define_insn "swapsf"
  1234.   [(set (match_operand:SF 0 "register_operand" "f")
  1235.     (match_operand:SF 1 "register_operand" "f"))
  1236.    (set (match_dup 1)
  1237.     (match_dup 0))]
  1238.   ""
  1239.   "*
  1240. {
  1241.   if (STACK_TOP_P (operands[0]))
  1242.     return AS1 (fxch,%1);
  1243.   else
  1244.     return AS1 (fxch,%0);
  1245. }")
  1246.  
  1247. (define_expand "movdf"
  1248.   [(set (match_operand:DF 0 "general_operand" "")
  1249.     (match_operand:DF 1 "general_operand" ""))]
  1250.   ""
  1251.   "
  1252. {
  1253.   /* Special case memory->memory moves and pushes */
  1254.   if (TARGET_MOVE
  1255.       && (reload_in_progress | reload_completed) == 0
  1256.       && GET_CODE (operands[0]) == MEM
  1257.       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode)))
  1258.     {
  1259.       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
  1260.                         ? gen_movdf_push
  1261.                         : gen_movdf_mem;
  1262.  
  1263.       emit_insn ((*genfunc) (operands[0], operands[1]));
  1264.       DONE;
  1265.     }
  1266.  
  1267.   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  1268.      indicate we need the pic register loaded.  This could be optimized into stores
  1269.      of constants if the target eventually moves to memory, but better safe than
  1270.      sorry.  */
  1271.   if (flag_pic
  1272.       && GET_CODE (operands[0]) != MEM
  1273.       && GET_CODE (operands[1]) == CONST_DOUBLE
  1274.       && !standard_80387_constant_p (operands[1]))
  1275.     {
  1276.       current_function_uses_pic_offset_table = 1;
  1277.     }
  1278. }")
  1279.  
  1280. (define_insn "movdf_push_nomove"
  1281.   [(set (match_operand:DF 0 "push_operand" "=<,<")
  1282.     (match_operand:DF 1 "general_operand" "gF,f"))]
  1283.   "!TARGET_MOVE"
  1284.   "*
  1285. {
  1286.   if (STACK_REG_P (operands[1]))
  1287.     {
  1288.       rtx xops[3];
  1289.  
  1290.       xops[0] = AT_SP (SFmode);
  1291.       xops[1] = GEN_INT (8);
  1292.       xops[2] = stack_pointer_rtx;
  1293.  
  1294.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1295.  
  1296.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1297.         output_asm_insn (AS1 (fstp%Q0,%0), xops);
  1298.       else
  1299.         output_asm_insn (AS1 (fst%Q0,%0), xops);
  1300.  
  1301.       RET;
  1302.     }
  1303.   else
  1304.     return output_move_double (operands);
  1305. }")
  1306.  
  1307. (define_insn "movdf_push"
  1308.   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<")
  1309.     (match_operand:DF 1 "general_operand" "rF,f,o,o,o"))
  1310.    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
  1311.    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
  1312.   ""
  1313.   "*
  1314. {
  1315.   if (STACK_REG_P (operands[1]))
  1316.     {
  1317.       rtx xops[3];
  1318.  
  1319.       xops[0] = AT_SP (SFmode);
  1320.       xops[1] = GEN_INT (8);
  1321.       xops[2] = stack_pointer_rtx;
  1322.  
  1323.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1324.  
  1325.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1326.         output_asm_insn (AS1 (fstp%Q0,%0), xops);
  1327.       else
  1328.         output_asm_insn (AS1 (fst%Q0,%0), xops);
  1329.  
  1330.       RET;
  1331.     }
  1332.  
  1333.   else if (GET_CODE (operands[1]) != MEM)
  1334.     return output_move_double (operands);
  1335.  
  1336.   else
  1337.     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);
  1338. }")
  1339.  
  1340. (define_insn "movdf_mem"
  1341.   [(set (match_operand:DF 0 "memory_operand" "=o,o")
  1342.     (match_operand:DF 1 "memory_operand" "o,o"))
  1343.    (clobber (match_scratch:SI 2 "=&r,&r"))
  1344.    (clobber (match_scratch:SI 3 "=&r,X"))]
  1345.   ""
  1346.   "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);")
  1347.  
  1348. ;; For the purposes of regclass, prefer FLOAT_REGS.
  1349. (define_insn "movdf_normal"
  1350.   [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
  1351.     (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  1352.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  1353.   "*
  1354. {
  1355.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1356.  
  1357.   /* First handle a `pop' insn or a `fld %st(0)' */
  1358.  
  1359.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1360.     {
  1361.       if (stack_top_dies)
  1362.     return AS1 (fstp,%y0);
  1363.       else
  1364.         return AS1 (fld,%y0);
  1365.     }
  1366.  
  1367.   /* Handle a transfer between the 387 and a 386 register */
  1368.  
  1369.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1370.     {
  1371.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1372.       RET;
  1373.     }
  1374.  
  1375.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1376.     {
  1377.       output_to_reg (operands[0], stack_top_dies);
  1378.       RET;
  1379.     }
  1380.  
  1381.   /* Handle other kinds of writes from the 387 */
  1382.  
  1383.   if (STACK_TOP_P (operands[1]))
  1384.     {
  1385.       if (stack_top_dies)
  1386.     return AS1 (fstp%z0,%y0);
  1387.       else
  1388.         return AS1 (fst%z0,%y0);
  1389.     }
  1390.  
  1391.   /* Handle other kinds of reads to the 387 */
  1392.  
  1393.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1394.     return output_move_const_single (operands);
  1395.  
  1396.   if (STACK_TOP_P (operands[0]))
  1397.     return AS1 (fld%z1,%y1);
  1398.  
  1399.   /* Handle all DFmode moves not involving the 387 */
  1400.  
  1401.   return output_move_double (operands);
  1402. }")
  1403.  
  1404. (define_insn "swapdf"
  1405.   [(set (match_operand:DF 0 "register_operand" "f")
  1406.     (match_operand:DF 1 "register_operand" "f"))
  1407.    (set (match_dup 1)
  1408.     (match_dup 0))]
  1409.   ""
  1410.   "*
  1411. {
  1412.   if (STACK_TOP_P (operands[0]))
  1413.     return AS1 (fxch,%1);
  1414.   else
  1415.     return AS1 (fxch,%0);
  1416. }")
  1417.  
  1418. (define_expand "movxf"
  1419.   [(set (match_operand:XF 0 "general_operand" "")
  1420.     (match_operand:XF 1 "general_operand" ""))]
  1421.   ""
  1422.   "
  1423. {
  1424.   /* Special case memory->memory moves and pushes */
  1425.   if (TARGET_MOVE
  1426.       && (reload_in_progress | reload_completed) == 0
  1427.       && GET_CODE (operands[0]) == MEM
  1428.       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode)))
  1429.     {
  1430.       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
  1431.                         ? gen_movxf_push
  1432.                         : gen_movxf_mem;
  1433.  
  1434.       emit_insn ((*genfunc) (operands[0], operands[1]));
  1435.       DONE;
  1436.     }
  1437.  
  1438.   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
  1439.      indicate we need the pic register loaded.  This could be optimized into stores
  1440.      of constants if the target eventually moves to memory, but better safe than
  1441.      sorry.  */
  1442.   if (flag_pic
  1443.       && GET_CODE (operands[0]) != MEM
  1444.       && GET_CODE (operands[1]) == CONST_DOUBLE
  1445.       && !standard_80387_constant_p (operands[1]))
  1446.     {
  1447.       current_function_uses_pic_offset_table = 1;
  1448.     }
  1449. }")
  1450.  
  1451.  
  1452. (define_insn "movxf_push_nomove"
  1453.   [(set (match_operand:XF 0 "push_operand" "=<,<")
  1454.      (match_operand:XF 1 "general_operand" "gF,f"))]
  1455.   "!TARGET_MOVE"
  1456.   "*
  1457. {
  1458.   if (STACK_REG_P (operands[1]))
  1459.     {
  1460.       rtx xops[3];
  1461.  
  1462.       xops[0] = AT_SP (SFmode);
  1463.       xops[1] = GEN_INT (12);
  1464.       xops[2] = stack_pointer_rtx;
  1465.  
  1466.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1467.       output_asm_insn (AS1 (fstp%T0,%0), xops);
  1468.       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1469.     output_asm_insn (AS1 (fld%T0,%0), xops);
  1470.  
  1471.       RET;
  1472.     }
  1473.   else
  1474.     return output_move_double (operands);
  1475.  }")
  1476.  
  1477. (define_insn "movxf_push"
  1478.   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
  1479.      (match_operand:XF 1 "general_operand" "rF,f,o,o,o"))
  1480.    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
  1481.    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
  1482.   ""
  1483.   "*
  1484. {
  1485.   if (STACK_REG_P (operands[1]))
  1486.     {
  1487.       rtx xops[3];
  1488.  
  1489.       xops[0] = AT_SP (SFmode);
  1490.       xops[1] = GEN_INT (12);
  1491.       xops[2] = stack_pointer_rtx;
  1492.  
  1493.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1494.       output_asm_insn (AS1 (fstp%T0,%0), xops);
  1495.       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1496.     output_asm_insn (AS1 (fld%T0,%0), xops);
  1497.  
  1498.       RET;
  1499.     }
  1500.  
  1501.   else if (GET_CODE (operands[1]) != MEM
  1502.        || GET_CODE (operands[2]) != REG)
  1503.     return output_move_double (operands);
  1504.  
  1505.   else
  1506.     return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);
  1507. }")
  1508.  
  1509. (define_insn "movxf_mem"
  1510.   [(set (match_operand:XF 0 "memory_operand" "=o,o")
  1511.     (match_operand:XF 1 "memory_operand" "o,o"))
  1512.    (clobber (match_scratch:SI 2 "=&r,&r"))
  1513.    (clobber (match_scratch:SI 3 "=&r,X"))]
  1514.   ""
  1515.   "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")
  1516.  
  1517. (define_insn "movxf_normal"
  1518.   [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
  1519.     (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  1520.   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
  1521.   "*
  1522. {
  1523.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1524.  
  1525.   /* First handle a `pop' insn or a `fld %st(0)' */
  1526.  
  1527.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1528.     {
  1529.       if (stack_top_dies)
  1530.     return AS1 (fstp,%y0);
  1531.       else
  1532.         return AS1 (fld,%y0);
  1533.     }
  1534.  
  1535.   /* Handle a transfer between the 387 and a 386 register */
  1536.  
  1537.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1538.     {
  1539.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1540.       RET;
  1541.     }
  1542.  
  1543.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1544.     {
  1545.       output_to_reg (operands[0], stack_top_dies);
  1546.       RET;
  1547.     }
  1548.  
  1549.   /* Handle other kinds of writes from the 387 */
  1550.  
  1551.   if (STACK_TOP_P (operands[1]))
  1552.     {
  1553.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1554.       if (! stack_top_dies)
  1555.     return AS1 (fld%z0,%y0);
  1556.  
  1557.       RET;
  1558.     }
  1559.  
  1560.   /* Handle other kinds of reads to the 387 */
  1561.  
  1562.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1563.     return output_move_const_single (operands);
  1564.  
  1565.   if (STACK_TOP_P (operands[0]))
  1566.        return AS1 (fld%z1,%y1);
  1567.  
  1568.   /* Handle all XFmode moves not involving the 387 */
  1569.  
  1570.   return output_move_double (operands);
  1571. }")
  1572.  
  1573. (define_insn "swapxf"
  1574.   [(set (match_operand:XF 0 "register_operand" "f")
  1575.     (match_operand:XF 1 "register_operand" "f"))
  1576.    (set (match_dup 1)
  1577.     (match_dup 0))]
  1578.   ""
  1579.   "*
  1580. {
  1581.   if (STACK_TOP_P (operands[0]))
  1582.     return AS1 (fxch,%1);
  1583.   else
  1584.     return AS1 (fxch,%0);
  1585. }")
  1586.  
  1587. (define_insn ""
  1588.   [(set (match_operand:DI 0 "push_operand" "=<,<,<,<")
  1589.     (match_operand:DI 1 "general_operand" "riF,o,o,o"))
  1590.    (clobber (match_scratch:SI 2 "=X,&r,&r,X"))
  1591.    (clobber (match_scratch:SI 3 "=X,&r,X,X"))]
  1592.   ""
  1593.   "*
  1594. {
  1595.   if (GET_CODE (operands[1]) != MEM)
  1596.     return output_move_double (operands);
  1597.  
  1598.   else
  1599.     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
  1600. }")
  1601.  
  1602. (define_insn "movdi"
  1603.   [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm")
  1604.     (match_operand:DI 1 "general_operand" "o,o,m,riF"))
  1605.    (clobber (match_scratch:SI 2 "=&r,&r,X,X"))
  1606.    (clobber (match_scratch:SI 3 "=&r,X,X,X"))]
  1607.   ""
  1608.   "*
  1609. {
  1610.   rtx low[2], high[2], xop[6];
  1611.  
  1612.   if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
  1613.     return output_move_double (operands);
  1614.   else
  1615.     return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
  1616. }")
  1617.  
  1618.  
  1619. ;;- conversion instructions
  1620. ;;- NONE
  1621.  
  1622. ;;- zero extension instructions
  1623. ;; See comments by `andsi' for when andl is faster than movzx.
  1624.  
  1625. (define_insn "zero_extendhisi2"
  1626.   [(set (match_operand:SI 0 "general_operand" "=r")
  1627.     (zero_extend:SI
  1628.      (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  1629.   ""
  1630.   "*
  1631. {
  1632.   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  1633.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1634.     {
  1635.       rtx xops[2];
  1636.       xops[0] = operands[0];
  1637.       xops[1] = GEN_INT (0xffff);
  1638.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1639.       RET;
  1640.     }
  1641.  
  1642. #ifdef INTEL_SYNTAX
  1643.   return AS2 (movzx,%1,%0);
  1644. #else
  1645.   return AS2 (movz%W0%L0,%1,%0);
  1646. #endif
  1647. }")
  1648.  
  1649. (define_insn "zero_extendqihi2"
  1650.   [(set (match_operand:HI 0 "general_operand" "=r")
  1651.     (zero_extend:HI
  1652.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1653.   ""
  1654.   "*
  1655. {
  1656.   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  1657.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1658.     {
  1659.       rtx xops[2];
  1660.       xops[0] = operands[0];
  1661.       xops[1] = GEN_INT (0xff);
  1662.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1663.       RET;
  1664.     }
  1665.  
  1666. #ifdef INTEL_SYNTAX
  1667.   return AS2 (movzx,%1,%0);
  1668. #else
  1669.   return AS2 (movz%B0%W0,%1,%0);
  1670. #endif
  1671. }")
  1672.  
  1673. (define_insn "zero_extendqisi2"
  1674.   [(set (match_operand:SI 0 "general_operand" "=r")
  1675.     (zero_extend:SI
  1676.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1677.   ""
  1678.   "*
  1679. {
  1680.   if ((!TARGET_386 || REGNO (operands[0]) == 0)
  1681.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1682.     {
  1683.       rtx xops[2];
  1684.       xops[0] = operands[0];
  1685.       xops[1] = GEN_INT (0xff);
  1686.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1687.       RET;
  1688.     }
  1689.  
  1690. #ifdef INTEL_SYNTAX
  1691.   return AS2 (movzx,%1,%0);
  1692. #else
  1693.   return AS2 (movz%B0%L0,%1,%0);
  1694. #endif
  1695. }")
  1696.  
  1697. (define_insn "zero_extendsidi2"
  1698.   [(set (match_operand:DI 0 "register_operand" "=r")
  1699.     (zero_extend:DI
  1700.      (match_operand:SI 1 "register_operand" "0")))]
  1701.   ""
  1702.   "*
  1703. {
  1704.   operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1705.   return AS2 (xor%L0,%0,%0);
  1706. }")
  1707.  
  1708. ;;- sign extension instructions
  1709.  
  1710. (define_insn "extendsidi2"
  1711.   [(set (match_operand:DI 0 "register_operand" "=r")
  1712.     (sign_extend:DI
  1713.      (match_operand:SI 1 "register_operand" "0")))]
  1714.   ""
  1715.   "*
  1716. {
  1717.   if (REGNO (operands[0]) == 0)
  1718.     {
  1719.       /* This used to be cwtl, but that extends HI to SI somehow.  */
  1720. #ifdef INTEL_SYNTAX
  1721.       return \"cdq\";
  1722. #else
  1723.       return \"cltd\";
  1724. #endif
  1725.     }
  1726.  
  1727.   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1728.   output_asm_insn (AS2 (mov%L0,%0,%1), operands);
  1729.  
  1730.   operands[0] = GEN_INT (31);
  1731.   return AS2 (sar%L1,%0,%1);
  1732. }")
  1733.  
  1734. ;; Note that the i386 programmers' manual says that the opcodes
  1735. ;; are named movsx..., but the assembler on Unix does not accept that.
  1736. ;; We use what the Unix assembler expects.
  1737.  
  1738. (define_insn "extendhisi2"
  1739.   [(set (match_operand:SI 0 "general_operand" "=r")
  1740.     (sign_extend:SI
  1741.      (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  1742.   ""
  1743.   "*
  1744. {
  1745.   if (REGNO (operands[0]) == 0
  1746.       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
  1747. #ifdef INTEL_SYNTAX
  1748.     return \"cwde\";
  1749. #else
  1750.     return \"cwtl\";
  1751. #endif
  1752.  
  1753. #ifdef INTEL_SYNTAX
  1754.   return AS2 (movsx,%1,%0);
  1755. #else
  1756.   return AS2 (movs%W0%L0,%1,%0);
  1757. #endif
  1758. }")
  1759.  
  1760. (define_insn "extendqihi2"
  1761.   [(set (match_operand:HI 0 "general_operand" "=r")
  1762.     (sign_extend:HI
  1763.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1764.   ""
  1765.   "*
  1766. {
  1767.   if (REGNO (operands[0]) == 0
  1768.       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
  1769.     return \"cbtw\";
  1770.  
  1771. #ifdef INTEL_SYNTAX
  1772.   return AS2 (movsx,%1,%0);
  1773. #else
  1774.   return AS2 (movs%B0%W0,%1,%0);
  1775. #endif
  1776. }")
  1777.  
  1778. (define_insn "extendqisi2"
  1779.   [(set (match_operand:SI 0 "general_operand" "=r")
  1780.     (sign_extend:SI
  1781.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1782.   ""
  1783.   "*
  1784. {
  1785. #ifdef INTEL_SYNTAX
  1786.   return AS2 (movsx,%1,%0);
  1787. #else
  1788.   return AS2 (movs%B0%L0,%1,%0);
  1789. #endif
  1790. }")
  1791.  
  1792. ;; Conversions between float and double.
  1793.  
  1794. (define_insn "extendsfdf2"
  1795.   [(set (match_operand:DF 0 "general_operand" "=fm,f")
  1796.     (float_extend:DF
  1797.      (match_operand:SF 1 "general_operand" "f,fm")))]
  1798.   "TARGET_80387"
  1799.   "*
  1800. {
  1801.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1802.  
  1803.   if (NON_STACK_REG_P (operands[1]))
  1804.     {
  1805.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1806.       RET;
  1807.     }
  1808.  
  1809.   if (NON_STACK_REG_P (operands[0]))
  1810.     {
  1811.       output_to_reg (operands[0], stack_top_dies);
  1812.       RET;
  1813.     }
  1814.  
  1815.   if (STACK_TOP_P (operands[0]))
  1816.     return AS1 (fld%z1,%y1);
  1817.  
  1818.   if (GET_CODE (operands[0]) == MEM)
  1819.     {
  1820.       if (stack_top_dies)
  1821.     return AS1 (fstp%z0,%y0);
  1822.       else
  1823.         return AS1 (fst%z0,%y0);
  1824.     }
  1825.  
  1826.   abort ();
  1827. }")
  1828.  
  1829. (define_insn "extenddfxf2"
  1830.   [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
  1831.     (float_extend:XF
  1832.      (match_operand:DF 1 "general_operand" "f,fm,!*r,f")))]
  1833.   "TARGET_80387"
  1834.   "*
  1835. {
  1836.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1837.  
  1838.   if (NON_STACK_REG_P (operands[1]))
  1839.     {
  1840.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1841.       RET;
  1842.     }
  1843.  
  1844.   if (NON_STACK_REG_P (operands[0]))
  1845.     {
  1846.       output_to_reg (operands[0], stack_top_dies);
  1847.       RET;
  1848.     }
  1849.  
  1850.   if (STACK_TOP_P (operands[0]))
  1851.     return AS1 (fld%z1,%y1);
  1852.  
  1853.   if (GET_CODE (operands[0]) == MEM)
  1854.     {
  1855.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1856.       if (! stack_top_dies)
  1857.     return AS1 (fld%z0,%y0);
  1858.       RET;
  1859.     }
  1860.  
  1861.   abort ();
  1862. }")
  1863.  
  1864. (define_insn "extendsfxf2"
  1865.   [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
  1866.     (float_extend:XF
  1867.      (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))]
  1868.   "TARGET_80387"
  1869.   "*
  1870. {
  1871.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1872.  
  1873.   if (NON_STACK_REG_P (operands[1]))
  1874.     {
  1875.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1876.       RET;
  1877.     }
  1878.  
  1879.   if (NON_STACK_REG_P (operands[0]))
  1880.     {
  1881.       output_to_reg (operands[0], stack_top_dies);
  1882.       RET;
  1883.     }
  1884.  
  1885.   if (STACK_TOP_P (operands[0]))
  1886.     return AS1 (fld%z1,%y1);
  1887.  
  1888.   if (GET_CODE (operands[0]) == MEM)
  1889.     {
  1890.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1891.       if (! stack_top_dies)
  1892.     return AS1 (fld%z0,%y0);
  1893.       RET;
  1894.     }
  1895.  
  1896.   abort ();
  1897. }")
  1898.  
  1899. (define_expand "truncdfsf2"
  1900.   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
  1901.            (float_truncate:SF
  1902.             (match_operand:DF 1 "register_operand" "")))
  1903.           (clobber (match_dup 2))])]
  1904.   "TARGET_80387"
  1905.   "
  1906. {
  1907.   operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
  1908. }")
  1909.  
  1910. ;; This cannot output into an f-reg because there is no way to be sure
  1911. ;; of truncating in that case.  Otherwise this is just like a simple move
  1912. ;; insn.  So we pretend we can output to a reg in order to get better
  1913. ;; register preferencing, but we really use a stack slot.
  1914.  
  1915. (define_insn ""
  1916.   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
  1917.     (float_truncate:SF
  1918.      (match_operand:DF 1 "register_operand" "0,f")))
  1919.    (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
  1920.   "TARGET_80387"
  1921.   "*
  1922. {
  1923.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1924.  
  1925.   if (GET_CODE (operands[0]) == MEM)
  1926.     {
  1927.       if (stack_top_dies)
  1928.     return AS1 (fstp%z0,%0);
  1929.       else
  1930.         return AS1 (fst%z0,%0);
  1931.     }
  1932.   else if (STACK_TOP_P (operands[0]))
  1933.     {
  1934.       output_asm_insn (AS1 (fstp%z2,%y2), operands);
  1935.       return AS1 (fld%z2,%y2);
  1936.     }
  1937.   else
  1938.     abort ();
  1939. }")
  1940.  
  1941. (define_insn "truncxfsf2"
  1942.   [(set (match_operand:SF 0 "general_operand" "=m,!*r")
  1943.     (float_truncate:SF
  1944.      (match_operand:XF 1 "register_operand" "f,f")))]
  1945.   "TARGET_80387"
  1946.   "*
  1947. {
  1948.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1949.  
  1950.   if (NON_STACK_REG_P (operands[0]))
  1951.     {
  1952.       if (stack_top_dies == 0)
  1953.     {
  1954.       output_asm_insn (AS1 (fld,%y1), operands);
  1955.       stack_top_dies = 1;
  1956.     }
  1957.       output_to_reg (operands[0], stack_top_dies);
  1958.       RET;
  1959.     }
  1960.   else if (GET_CODE (operands[0]) == MEM)
  1961.     {
  1962.       if (stack_top_dies)
  1963.     return AS1 (fstp%z0,%0);
  1964.       else
  1965.     {
  1966.       output_asm_insn (AS1 (fld,%y1), operands);
  1967.       return AS1 (fstp%z0,%0);
  1968.     }
  1969.     }
  1970.   else
  1971.     abort ();
  1972. }")
  1973.  
  1974. (define_insn "truncxfdf2"
  1975.   [(set (match_operand:DF 0 "general_operand" "=m,!*r")
  1976.     (float_truncate:DF
  1977.      (match_operand:XF 1 "register_operand" "f,f")))]
  1978.   "TARGET_80387"
  1979.   "*
  1980. {
  1981.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1982.  
  1983.   if (NON_STACK_REG_P (operands[0]))
  1984.     {
  1985.       if (stack_top_dies == 0)
  1986.     {
  1987.       output_asm_insn (AS1 (fld,%y1), operands);
  1988.       stack_top_dies = 1;
  1989.     }
  1990.       output_to_reg (operands[0], stack_top_dies);
  1991.       RET;
  1992.     }
  1993.   else if (GET_CODE (operands[0]) == MEM)
  1994.     {
  1995.       if (stack_top_dies)
  1996.     return AS1 (fstp%z0,%0);
  1997.       else
  1998.     {
  1999.       output_asm_insn (AS1 (fld,%y1), operands);
  2000.       return AS1 (fstp%z0,%0);
  2001.     }
  2002.     }
  2003.   else
  2004.     abort ();
  2005. }")
  2006.  
  2007.  
  2008. ;; The 387 requires that the stack top dies after converting to DImode.
  2009.  
  2010. ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
  2011. ;; doing a signed conversion to DImode, and then taking just the low
  2012. ;; part.
  2013.  
  2014. (define_expand "fixuns_truncxfsi2"
  2015.   [(set (match_dup 4)
  2016.     (match_operand:XF 1 "register_operand" ""))
  2017.    (parallel [(set (match_dup 2)
  2018.            (fix:DI (fix:XF (match_dup 4))))
  2019.           (clobber (match_dup 4))
  2020.           (clobber (match_dup 5))
  2021.           (clobber (match_dup 6))
  2022.           (clobber (match_scratch:SI 7 ""))])
  2023.    (set (match_operand:SI 0 "general_operand" "")
  2024.     (match_dup 3))]
  2025.   "TARGET_80387"
  2026.   "
  2027. {
  2028.   operands[2] = gen_reg_rtx (DImode);
  2029.   operands[3] = gen_lowpart (SImode, operands[2]);
  2030.   operands[4] = gen_reg_rtx (XFmode);
  2031.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  2032.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  2033. }")
  2034.  
  2035. (define_expand "fixuns_truncdfsi2"
  2036.   [(set (match_dup 4)
  2037.     (match_operand:DF 1 "register_operand" ""))
  2038.    (parallel [(set (match_dup 2)
  2039.            (fix:DI (fix:DF (match_dup 4))))
  2040.           (clobber (match_dup 4))
  2041.           (clobber (match_dup 5))
  2042.           (clobber (match_dup 6))
  2043.           (clobber (match_scratch:SI 7 ""))])
  2044.    (set (match_operand:SI 0 "general_operand" "")
  2045.     (match_dup 3))]
  2046.   "TARGET_80387"
  2047.   "
  2048. {
  2049.   operands[2] = gen_reg_rtx (DImode);
  2050.   operands[3] = gen_lowpart (SImode, operands[2]);
  2051.   operands[4] = gen_reg_rtx (DFmode);
  2052.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  2053.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  2054. }")
  2055.  
  2056. (define_expand "fixuns_truncsfsi2"
  2057.   [(set (match_dup 4)
  2058.     (match_operand:SF 1 "register_operand" ""))
  2059.    (parallel [(set (match_dup 2)
  2060.            (fix:DI (fix:SF (match_dup 4))))
  2061.           (clobber (match_dup 4))
  2062.           (clobber (match_dup 5))
  2063.           (clobber (match_dup 6))
  2064.           (clobber (match_scratch:SI 7 ""))])
  2065.    (set (match_operand:SI 0 "general_operand" "")
  2066.     (match_dup 3))]
  2067.   "TARGET_80387"
  2068.   "
  2069. {
  2070.   operands[2] = gen_reg_rtx (DImode);
  2071.   operands[3] = gen_lowpart (SImode, operands[2]);
  2072.   operands[4] = gen_reg_rtx (SFmode);
  2073.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  2074.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  2075. }")
  2076.  
  2077. ;; Signed conversion to DImode.
  2078.  
  2079. (define_expand "fix_truncxfdi2"
  2080.   [(set (match_dup 2)
  2081.     (match_operand:XF 1 "register_operand" ""))
  2082.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  2083.            (fix:DI (fix:XF (match_dup 2))))
  2084.           (clobber (match_dup 2))
  2085.           (clobber (match_dup 3))
  2086.           (clobber (match_dup 4))
  2087.           (clobber (match_scratch:SI 5 ""))])]
  2088.   "TARGET_80387"
  2089.   "
  2090. {
  2091.   operands[1] = copy_to_mode_reg (XFmode, operands[1]);
  2092.   operands[2] = gen_reg_rtx (XFmode);
  2093.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  2094.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  2095. }")
  2096.  
  2097. (define_expand "fix_truncdfdi2"
  2098.   [(set (match_dup 2)
  2099.     (match_operand:DF 1 "register_operand" ""))
  2100.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  2101.            (fix:DI (fix:DF (match_dup 2))))
  2102.           (clobber (match_dup 2))
  2103.           (clobber (match_dup 3))
  2104.           (clobber (match_dup 4))
  2105.           (clobber (match_scratch:SI 5 ""))])]
  2106.   "TARGET_80387"
  2107.   "
  2108. {
  2109.   operands[1] = copy_to_mode_reg (DFmode, operands[1]);
  2110.   operands[2] = gen_reg_rtx (DFmode);
  2111.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  2112.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  2113. }")
  2114.  
  2115. (define_expand "fix_truncsfdi2"
  2116.   [(set (match_dup 2)
  2117.     (match_operand:SF 1 "register_operand" ""))
  2118.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  2119.            (fix:DI (fix:SF (match_dup 2))))
  2120.           (clobber (match_dup 2))
  2121.           (clobber (match_dup 3))
  2122.           (clobber (match_dup 4))
  2123.           (clobber (match_scratch:SI 5 ""))])]
  2124.   "TARGET_80387"
  2125.   "
  2126. {
  2127.   operands[1] = copy_to_mode_reg (SFmode, operands[1]);
  2128.   operands[2] = gen_reg_rtx (SFmode);
  2129.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  2130.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  2131. }")
  2132.  
  2133. ;; These match a signed conversion of either DFmode or SFmode to DImode.
  2134.  
  2135. (define_insn ""
  2136.   [(set (match_operand:DI 0 "general_operand" "=rm")
  2137.     (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  2138.    (clobber (match_dup 1))
  2139.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2140.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2141.    (clobber (match_scratch:SI 4 "=&q"))]
  2142.   "TARGET_80387"
  2143.   "* return output_fix_trunc (insn, operands);")
  2144.  
  2145. (define_insn ""
  2146.   [(set (match_operand:DI 0 "general_operand" "=rm")
  2147.     (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  2148.    (clobber (match_dup 1))
  2149.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2150.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2151.    (clobber (match_scratch:SI 4 "=&q"))]
  2152.   "TARGET_80387"
  2153.   "* return output_fix_trunc (insn, operands);")
  2154.  
  2155. (define_insn ""
  2156.   [(set (match_operand:DI 0 "general_operand" "=rm")
  2157.     (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  2158.    (clobber (match_dup 1))
  2159.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2160.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2161.    (clobber (match_scratch:SI 4 "=&q"))]
  2162.   "TARGET_80387"
  2163.   "* return output_fix_trunc (insn, operands);")
  2164.  
  2165. ;; Signed MODE_FLOAT conversion to SImode.
  2166.  
  2167. (define_expand "fix_truncxfsi2"
  2168.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  2169.            (fix:SI
  2170.             (fix:XF (match_operand:XF 1 "register_operand" ""))))
  2171.           (clobber (match_dup 2))
  2172.           (clobber (match_dup 3))
  2173.           (clobber (match_scratch:SI 4 ""))])]
  2174.   "TARGET_80387"
  2175.   "
  2176. {
  2177.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  2178.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  2179. }")
  2180.  
  2181. (define_expand "fix_truncdfsi2"
  2182.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  2183.            (fix:SI
  2184.             (fix:DF (match_operand:DF 1 "register_operand" ""))))
  2185.           (clobber (match_dup 2))
  2186.           (clobber (match_dup 3))
  2187.           (clobber (match_scratch:SI 4 ""))])]
  2188.   "TARGET_80387"
  2189.   "
  2190. {
  2191.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  2192.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  2193. }")
  2194.  
  2195. (define_expand "fix_truncsfsi2"
  2196.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  2197.            (fix:SI
  2198.             (fix:SF (match_operand:SF 1 "register_operand" ""))))
  2199.           (clobber (match_dup 2))
  2200.           (clobber (match_dup 3))
  2201.           (clobber (match_scratch:SI 4 ""))])]
  2202.   "TARGET_80387"
  2203.   "
  2204. {
  2205.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  2206.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  2207. }")
  2208.  
  2209. (define_insn ""
  2210.   [(set (match_operand:SI 0 "general_operand" "=rm")
  2211.     (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  2212.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2213.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2214.    (clobber (match_scratch:SI 4 "=&q"))]
  2215.   "TARGET_80387"
  2216.   "* return output_fix_trunc (insn, operands);")
  2217.  
  2218. (define_insn ""
  2219.   [(set (match_operand:SI 0 "general_operand" "=rm")
  2220.     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  2221.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2222.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2223.    (clobber (match_scratch:SI 4 "=&q"))]
  2224.   "TARGET_80387"
  2225.   "* return output_fix_trunc (insn, operands);")
  2226.  
  2227. (define_insn ""
  2228.   [(set (match_operand:SI 0 "general_operand" "=rm")
  2229.     (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  2230.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  2231.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  2232.    (clobber (match_scratch:SI 4 "=&q"))]
  2233.   "TARGET_80387"
  2234.   "* return output_fix_trunc (insn, operands);")
  2235.  
  2236. ;; Conversion between fixed point and floating point.
  2237. ;; The actual pattern that matches these is at the end of this file.
  2238.  
  2239. ;; ??? Possibly represent floatunssidf2 here in gcc2.
  2240.  
  2241. (define_expand "floatsisf2"
  2242.   [(set (match_operand:SF 0 "register_operand" "")
  2243.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
  2244.   "TARGET_80387"
  2245.   "")
  2246.  
  2247. (define_expand "floatdisf2"
  2248.   [(set (match_operand:SF 0 "register_operand" "")
  2249.     (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
  2250.   "TARGET_80387"
  2251.   "")
  2252.  
  2253. (define_expand "floatsidf2"
  2254.   [(set (match_operand:DF 0 "register_operand" "")
  2255.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
  2256.   "TARGET_80387"
  2257.   "")
  2258.  
  2259. (define_expand "floatdidf2"
  2260.   [(set (match_operand:DF 0 "register_operand" "")
  2261.     (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
  2262.   "TARGET_80387"
  2263.   "")
  2264.  
  2265. (define_expand "floatsixf2"
  2266.   [(set (match_operand:XF 0 "register_operand" "")
  2267.     (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
  2268.   "TARGET_80387"
  2269.   "")
  2270.  
  2271. (define_expand "floatdixf2"
  2272.   [(set (match_operand:XF 0 "register_operand" "")
  2273.     (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
  2274.   "TARGET_80387"
  2275.   "")
  2276.  
  2277. ;; This will convert from SImode or DImode to MODE_FLOAT.
  2278.  
  2279. (define_insn ""
  2280.   [(set (match_operand:XF 0 "register_operand" "=f")
  2281.     (float:XF (match_operand:DI 1 "general_operand" "rm")))]
  2282.   "TARGET_80387"
  2283.   "*
  2284. {
  2285.   if (NON_STACK_REG_P (operands[1]))
  2286.     {
  2287.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2288.       RET;
  2289.     }
  2290.   else if (GET_CODE (operands[1]) == MEM)
  2291.     return AS1 (fild%z1,%1);
  2292.   else
  2293.     abort ();
  2294. }")
  2295.  
  2296. (define_insn ""
  2297.   [(set (match_operand:DF 0 "register_operand" "=f")
  2298.     (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
  2299.   "TARGET_80387"
  2300.   "*
  2301. {
  2302.   if (NON_STACK_REG_P (operands[1]))
  2303.     {
  2304.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2305.       RET;
  2306.     }
  2307.   else if (GET_CODE (operands[1]) == MEM)
  2308.     return AS1 (fild%z1,%1);
  2309.   else
  2310.     abort ();
  2311. }")
  2312.  
  2313. (define_insn ""
  2314.   [(set (match_operand:SF 0 "register_operand" "=f")
  2315.     (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
  2316.   "TARGET_80387"
  2317.   "*
  2318. {
  2319.   if (NON_STACK_REG_P (operands[1]))
  2320.     {
  2321.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2322.       RET;
  2323.     }
  2324.   else if (GET_CODE (operands[1]) == MEM)
  2325.     return AS1 (fild%z1,%1);
  2326.   else
  2327.     abort ();
  2328. }")
  2329.  
  2330. (define_insn ""
  2331.   [(set (match_operand:DF 0 "register_operand" "=f")
  2332.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  2333.   "TARGET_80387"
  2334.   "*
  2335. {
  2336.   if (NON_STACK_REG_P (operands[1]))
  2337.     {
  2338.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2339.       RET;
  2340.     }
  2341.   else if (GET_CODE (operands[1]) == MEM)
  2342.     return AS1 (fild%z1,%1);
  2343.   else
  2344.     abort ();
  2345. }")
  2346.  
  2347. (define_insn ""
  2348.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  2349.     (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
  2350.   "TARGET_80387"
  2351.   "*
  2352. {
  2353.   if (NON_STACK_REG_P (operands[1]))
  2354.     {
  2355.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2356.       RET;
  2357.     }
  2358.   else if (GET_CODE (operands[1]) == MEM)
  2359.     return AS1 (fild%z1,%1);
  2360.   else
  2361.     abort ();
  2362. }")
  2363.  
  2364. (define_insn ""
  2365.   [(set (match_operand:SF 0 "register_operand" "=f")
  2366.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  2367.   "TARGET_80387"
  2368.   "*
  2369. {
  2370.   if (NON_STACK_REG_P (operands[1]))
  2371.     {
  2372.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2373.       RET;
  2374.     }
  2375.   else if (GET_CODE (operands[1]) == MEM)
  2376.     return AS1 (fild%z1,%1);
  2377.   else
  2378.     abort ();
  2379. }")
  2380.  
  2381. ;;- add instructions
  2382.  
  2383. (define_insn "adddi3"
  2384.   [(set (match_operand:DI 0 "general_operand" "=&r,ro,o,&r,ro,o,&r,o,o,o")
  2385.     (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,o,riF,o,or,riF,riF,o")
  2386.          (match_operand:DI 2 "general_operand" "o,riF,o,0,0,0,oriF,riF,o,o")))
  2387.    (clobber (match_scratch:SI 3 "=X,X,&r,X,&r,&r,X,&r,&r,&r"))]
  2388.   ""
  2389.   "*
  2390. {
  2391.   rtx low[3], high[3], xops[7], temp;
  2392.  
  2393.   CC_STATUS_INIT;
  2394.  
  2395.   if (rtx_equal_p (operands[0], operands[2]))
  2396.     {
  2397.       temp = operands[1];
  2398.       operands[1] = operands[2];
  2399.       operands[2] = temp;
  2400.     }
  2401.  
  2402.   split_di (operands, 3, low, high);
  2403.   if (!rtx_equal_p (operands[0], operands[1]))
  2404.     {
  2405.       xops[0] = high[0];
  2406.       xops[1] = low[0];
  2407.       xops[2] = high[1];
  2408.       xops[3] = low[1];
  2409.  
  2410.       if (GET_CODE (operands[0]) != MEM)
  2411.     {
  2412.       output_asm_insn (AS2 (mov%L1,%3,%1), xops);
  2413.       output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  2414.     }
  2415.       else
  2416.     {
  2417.       xops[4] = high[2];
  2418.       xops[5] = low[2];
  2419.       xops[6] = operands[3];
  2420.       output_asm_insn (AS2 (mov%L6,%3,%6), xops);
  2421.       output_asm_insn (AS2 (add%L6,%5,%6), xops);
  2422.       output_asm_insn (AS2 (mov%L1,%6,%1), xops);
  2423.       output_asm_insn (AS2 (mov%L6,%2,%6), xops);
  2424.       output_asm_insn (AS2 (adc%L6,%4,%6), xops);
  2425.       output_asm_insn (AS2 (mov%L0,%6,%0), xops);
  2426.       RET;
  2427.     }
  2428.     }
  2429.  
  2430.   if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
  2431.     {
  2432.       xops[0] = high[0];
  2433.       xops[1] = low[0];
  2434.       xops[2] = high[2];
  2435.       xops[3] = low[2];
  2436.       xops[4] = operands[3];
  2437.  
  2438.       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
  2439.       output_asm_insn (AS2 (add%L1,%4,%1), xops);
  2440.       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
  2441.       output_asm_insn (AS2 (adc%L0,%4,%0), xops);
  2442.     }
  2443.  
  2444.   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  2445.     {
  2446.       output_asm_insn (AS2 (add%L0,%2,%0), low);
  2447.       output_asm_insn (AS2 (adc%L0,%2,%0), high);
  2448.     }
  2449.  
  2450.   else
  2451.     output_asm_insn (AS2 (add%L0,%2,%0), high);
  2452.  
  2453.   RET;
  2454. }")
  2455.  
  2456. ;; On a 486, it is faster to do movl/addl than to do a single leal if
  2457. ;; operands[1] and operands[2] are both registers.
  2458.  
  2459. (define_insn "addsi3"
  2460.   [(set (match_operand:SI 0 "general_operand" "=?r,rm,r")
  2461.     (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
  2462.          (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
  2463.   ""
  2464.   "*
  2465. {
  2466.   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  2467.     {
  2468.       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  2469.     return AS2 (add%L0,%1,%0);
  2470.  
  2471.       if (operands[2] == stack_pointer_rtx)
  2472.     {
  2473.       rtx temp;
  2474.  
  2475.       temp = operands[1];
  2476.       operands[1] = operands[2];
  2477.       operands[2] = temp;
  2478.     }
  2479.  
  2480.       if (operands[2] != stack_pointer_rtx)
  2481.     {
  2482.       CC_STATUS_INIT;
  2483.       operands[1] = SET_SRC (PATTERN (insn));
  2484.       return AS2 (lea%L0,%a1,%0);
  2485.     }
  2486.  
  2487.       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  2488.     }
  2489.  
  2490.   if (operands[2] == const1_rtx)
  2491.     return AS1 (inc%L0,%0);
  2492.  
  2493.   if (operands[2] == constm1_rtx)
  2494.     return AS1 (dec%L0,%0);
  2495.  
  2496.   return AS2 (add%L0,%2,%0);
  2497. }")
  2498.  
  2499. ;; ??? `lea' here, for three operand add?  If leaw is used, only %bx,
  2500. ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
  2501. ;; able to handle the operand.  But leal always works?
  2502.  
  2503. (define_insn "addhi3"
  2504.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2505.     (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
  2506.          (match_operand:HI 2 "general_operand" "ri,rm")))]
  2507.   ""
  2508.   "*
  2509. {
  2510.   /* ??? what about offsettable memory references? */
  2511.   if (QI_REG_P (operands[0])
  2512.       && GET_CODE (operands[2]) == CONST_INT
  2513.       && (INTVAL (operands[2]) & 0xff) == 0)
  2514.     {
  2515.       int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
  2516.       CC_STATUS_INIT;
  2517.  
  2518.       if (byteval == 1)
  2519.     return AS1 (inc%B0,%h0);
  2520.       else if (byteval == 255)
  2521.     return AS1 (dec%B0,%h0);
  2522.  
  2523.       operands[2] = GEN_INT (byteval);
  2524.       return AS2 (add%B0,%2,%h0);
  2525.     }
  2526.  
  2527.   if (operands[2] == const1_rtx)
  2528.     return AS1 (inc%W0,%0);
  2529.  
  2530.   if (operands[2] == constm1_rtx
  2531.       || (GET_CODE (operands[2]) == CONST_INT
  2532.       && INTVAL (operands[2]) == 65535))
  2533.     return AS1 (dec%W0,%0);
  2534.  
  2535.   return AS2 (add%W0,%2,%0);
  2536. }")
  2537.  
  2538. (define_insn "addqi3"
  2539.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2540.     (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
  2541.          (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2542.   ""
  2543.   "*
  2544. {
  2545.   if (operands[2] == const1_rtx)
  2546.     return AS1 (inc%B0,%0);
  2547.  
  2548.   if (operands[2] == constm1_rtx
  2549.       || (GET_CODE (operands[2]) == CONST_INT
  2550.       && INTVAL (operands[2]) == 255))
  2551.     return AS1 (dec%B0,%0);
  2552.  
  2553.   return AS2 (add%B0,%2,%0);
  2554. }")
  2555.  
  2556. ;Lennart Augustsson <augustss@cs.chalmers.se>
  2557. ;says this pattern just makes slower code:
  2558. ;    pushl    %ebp
  2559. ;    addl    $-80,(%esp)
  2560. ;instead of
  2561. ;    leal    -80(%ebp),%eax
  2562. ;    pushl    %eax
  2563. ;
  2564. ;(define_insn ""
  2565. ;  [(set (match_operand:SI 0 "push_operand" "=<")
  2566. ;    (plus:SI (match_operand:SI 1 "general_operand" "%r")
  2567. ;         (match_operand:SI 2 "general_operand" "ri")))]
  2568. ;  ""
  2569. ;  "*
  2570. ;{
  2571. ;  rtx xops[4];
  2572. ;  xops[0] = operands[0];
  2573. ;  xops[1] = operands[1];
  2574. ;  xops[2] = operands[2];
  2575. ;  xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
  2576. ;  output_asm_insn (\"push%z1 %1\", xops);
  2577. ;  output_asm_insn (AS2 (add%z3,%2,%3), xops);
  2578. ;  RET;
  2579. ;}")
  2580.  
  2581. ;; addsi3 is faster, so put this after.
  2582.  
  2583. (define_insn "movsi_lea"
  2584.   [(set (match_operand:SI 0 "register_operand" "=r")
  2585.         (match_operand:QI 1 "address_operand" "p"))]
  2586.   ""
  2587.   "*
  2588. {
  2589.   CC_STATUS_INIT;
  2590.   /* Adding a constant to a register is faster with an add.  */
  2591.   /* ??? can this ever happen? */
  2592.   if (GET_CODE (operands[1]) == PLUS
  2593.       && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
  2594.       && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
  2595.     {
  2596.       operands[1] = XEXP (operands[1], 1);
  2597.  
  2598.       if (operands[1] == const1_rtx)
  2599.         return AS1 (inc%L0,%0);
  2600.  
  2601.       if (operands[1] == constm1_rtx)
  2602.         return AS1 (dec%L0,%0);
  2603.  
  2604.       return AS2 (add%L0,%1,%0);
  2605.     }
  2606.   return AS2 (lea%L0,%a1,%0);
  2607. }")
  2608.  
  2609. ;; The patterns that match these are at the end of this file.
  2610.  
  2611. (define_expand "addxf3"
  2612.   [(set (match_operand:XF 0 "register_operand" "")
  2613.     (plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2614.          (match_operand:XF 2 "nonimmediate_operand" "")))]
  2615.   "TARGET_80387"
  2616.   "")
  2617.  
  2618. (define_expand "adddf3"
  2619.   [(set (match_operand:DF 0 "register_operand" "")
  2620.     (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2621.          (match_operand:DF 2 "nonimmediate_operand" "")))]
  2622.   "TARGET_80387"
  2623.   "")
  2624.  
  2625. (define_expand "addsf3"
  2626.   [(set (match_operand:SF 0 "register_operand" "")
  2627.     (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2628.          (match_operand:SF 2 "nonimmediate_operand" "")))]
  2629.   "TARGET_80387"
  2630.   "")
  2631.  
  2632. ;;- subtract instructions
  2633.  
  2634. (define_insn "subdi3"
  2635.   [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o")
  2636.     (minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o")
  2637.           (match_operand:DI 2 "general_operand" "o,riF,roiF,riF,o")))
  2638.    (clobber (match_scratch:SI 3 "=X,X,X,&r,&r"))]
  2639.   ""
  2640.   "*
  2641. {
  2642.   rtx low[3], high[3], xops[7];
  2643.  
  2644.   CC_STATUS_INIT;
  2645.  
  2646.   split_di (operands, 3, low, high);
  2647.  
  2648.   if (!rtx_equal_p (operands[0], operands[1]))
  2649.     {
  2650.       xops[0] = high[0];
  2651.       xops[1] = low[0];
  2652.       xops[2] = high[1];
  2653.       xops[3] = low[1];
  2654.  
  2655.       if (GET_CODE (operands[0]) != MEM)
  2656.     {
  2657.       output_asm_insn (AS2 (mov%L1,%3,%1), xops);
  2658.       output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  2659.     }
  2660.       else
  2661.     {
  2662.       xops[4] = high[2];
  2663.       xops[5] = low[2];
  2664.       xops[6] = operands[3];
  2665.       output_asm_insn (AS2 (mov%L6,%3,%6), xops);
  2666.       output_asm_insn (AS2 (sub%L6,%5,%6), xops);
  2667.       output_asm_insn (AS2 (mov%L1,%6,%1), xops);
  2668.       output_asm_insn (AS2 (mov%L6,%2,%6), xops);
  2669.       output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
  2670.       output_asm_insn (AS2 (mov%L0,%6,%0), xops);
  2671.       RET;
  2672.     }
  2673.     }
  2674.  
  2675.   if (GET_CODE (operands[3]) == REG)
  2676.     {
  2677.       xops[0] = high[0];
  2678.       xops[1] = low[0];
  2679.       xops[2] = high[2];
  2680.       xops[3] = low[2];
  2681.       xops[4] = operands[3];
  2682.  
  2683.       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
  2684.       output_asm_insn (AS2 (sub%L1,%4,%1), xops);
  2685.       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
  2686.       output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
  2687.     }
  2688.  
  2689.   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  2690.     {
  2691.       output_asm_insn (AS2 (sub%L0,%2,%0), low);
  2692.       output_asm_insn (AS2 (sbb%L0,%2,%0), high);
  2693.     }
  2694.  
  2695.   else
  2696.     output_asm_insn (AS2 (sub%L0,%2,%0), high);
  2697.  
  2698.   RET;
  2699. }")
  2700.  
  2701. (define_insn "subsi3"
  2702.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  2703.     (minus:SI (match_operand:SI 1 "general_operand" "0,0")
  2704.           (match_operand:SI 2 "general_operand" "ri,rm")))]
  2705.   ""
  2706.   "* return AS2 (sub%L0,%2,%0);")
  2707.  
  2708. (define_insn "subhi3"
  2709.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2710.     (minus:HI (match_operand:HI 1 "general_operand" "0,0")
  2711.           (match_operand:HI 2 "general_operand" "ri,rm")))]
  2712.   ""
  2713.   "* return AS2 (sub%W0,%2,%0);")
  2714.  
  2715. (define_insn "subqi3"
  2716.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2717.     (minus:QI (match_operand:QI 1 "general_operand" "0,0")
  2718.           (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2719.   ""
  2720.   "* return AS2 (sub%B0,%2,%0);")
  2721.  
  2722. ;; The patterns that match these are at the end of this file.
  2723.  
  2724. (define_expand "subxf3"
  2725.   [(set (match_operand:XF 0 "register_operand" "")
  2726.     (minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2727.           (match_operand:XF 2 "nonimmediate_operand" "")))]
  2728.   "TARGET_80387"
  2729.   "")
  2730.  
  2731. (define_expand "subdf3"
  2732.   [(set (match_operand:DF 0 "register_operand" "")
  2733.     (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2734.           (match_operand:DF 2 "nonimmediate_operand" "")))]
  2735.   "TARGET_80387"
  2736.   "")
  2737.  
  2738. (define_expand "subsf3"
  2739.   [(set (match_operand:SF 0 "register_operand" "")
  2740.     (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2741.           (match_operand:SF 2 "nonimmediate_operand" "")))]
  2742.   "TARGET_80387"
  2743.   "")
  2744.  
  2745. ;;- multiply instructions
  2746.  
  2747. ;(define_insn "mulqi3"
  2748. ;  [(set (match_operand:QI 0 "general_operand" "=a")
  2749. ;    (mult:QI (match_operand:QI 1 "general_operand" "%0")
  2750. ;         (match_operand:QI 2 "general_operand" "qm")))]
  2751. ;  ""
  2752. ;  "imul%B0 %2,%0")
  2753.  
  2754. (define_insn ""
  2755.   [(set (match_operand:HI 0 "general_operand" "=r")
  2756.     (mult:HI (match_operand:HI 1 "general_operand" "%0")
  2757.          (match_operand:HI 2 "general_operand" "r")))]
  2758.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  2759.   "* return AS2 (imul%W0,%2,%0);")
  2760.  
  2761. (define_insn "mulhi3"
  2762.   [(set (match_operand:HI 0 "general_operand" "=r,r")
  2763.     (mult:HI (match_operand:HI 1 "general_operand" "%0,rm")
  2764.          (match_operand:HI 2 "general_operand" "g,i")))]
  2765.   ""
  2766.   "*
  2767. {
  2768.   if (GET_CODE (operands[1]) == REG
  2769.       && REGNO (operands[1]) == REGNO (operands[0])
  2770.       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
  2771.     /* Assembler has weird restrictions.  */
  2772.     return AS2 (imul%W0,%2,%0);
  2773.   return AS3 (imul%W0,%2,%1,%0);
  2774. }")
  2775.  
  2776. (define_insn ""
  2777.   [(set (match_operand:SI 0 "general_operand" "=r")
  2778.     (mult:SI (match_operand:SI 1 "general_operand" "%0")
  2779.          (match_operand:SI 2 "general_operand" "r")))]
  2780.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  2781.   "* return AS2 (imul%L0,%2,%0);")
  2782.  
  2783. (define_insn "mulsi3"
  2784.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  2785.     (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
  2786.          (match_operand:SI 2 "general_operand" "g,i")))]
  2787.   ""
  2788.   "*
  2789. {
  2790.   if (GET_CODE (operands[1]) == REG
  2791.       && REGNO (operands[1]) == REGNO (operands[0])
  2792.       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
  2793.     /* Assembler has weird restrictions.  */
  2794.     return AS2 (imul%L0,%2,%0);
  2795.   return AS3 (imul%L0,%2,%1,%0);
  2796. }")
  2797.  
  2798. (define_insn "umulqihi3"
  2799.   [(set (match_operand:HI 0 "general_operand" "=a")
  2800.     (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
  2801.          (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  2802.   ""
  2803.   "mul%B0 %2")
  2804.  
  2805. (define_insn "mulqihi3"
  2806.   [(set (match_operand:HI 0 "general_operand" "=a")
  2807.     (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
  2808.          (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  2809.   ""
  2810.   "imul%B0 %2")
  2811.  
  2812. (define_insn "umulsidi3"
  2813.   [(set (match_operand:DI 0 "register_operand" "=A")
  2814.     (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
  2815.          (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
  2816.   "TARGET_WIDE_MULTIPLY"
  2817.   "mul%L0 %2")
  2818.  
  2819. (define_insn "mulsidi3"
  2820.   [(set (match_operand:DI 0 "register_operand" "=A")
  2821.     (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
  2822.          (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
  2823.   "TARGET_WIDE_MULTIPLY"
  2824.   "imul%L0 %2")
  2825.  
  2826. (define_insn "umulsi3_highpart"
  2827.   [(set (match_operand:SI 0 "register_operand" "=d")
  2828.     (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
  2829.                        (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
  2830.                   (const_int 32))))
  2831.    (clobber (match_scratch:SI 3 "=a"))]
  2832.   "TARGET_WIDE_MULTIPLY"
  2833.   "mul%L0 %2")
  2834.  
  2835. (define_insn "smulsi3_highpart"
  2836.   [(set (match_operand:SI 0 "register_operand" "=d")
  2837.     (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
  2838.                        (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
  2839.                   (const_int 32))))
  2840.    (clobber (match_scratch:SI 3 "=a"))]
  2841.   "TARGET_WIDE_MULTIPLY"
  2842.   "imul%L0 %2")
  2843.  
  2844. ;; The patterns that match these are at the end of this file.
  2845.  
  2846. (define_expand "mulxf3"
  2847.   [(set (match_operand:XF 0 "register_operand" "")
  2848.     (mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2849.          (match_operand:XF 2 "nonimmediate_operand" "")))]
  2850.   "TARGET_80387"
  2851.   "")
  2852.  
  2853. (define_expand "muldf3"
  2854.   [(set (match_operand:DF 0 "register_operand" "")
  2855.     (mult:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2856.          (match_operand:DF 2 "nonimmediate_operand" "")))]
  2857.   "TARGET_80387"
  2858.   "")
  2859.  
  2860. (define_expand "mulsf3"
  2861.   [(set (match_operand:SF 0 "register_operand" "")
  2862.     (mult:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2863.          (match_operand:SF 2 "nonimmediate_operand" "")))]
  2864.   "TARGET_80387"
  2865.   "")
  2866.  
  2867. ;;- divide instructions
  2868.  
  2869. (define_insn "divqi3"
  2870.   [(set (match_operand:QI 0 "general_operand" "=a")
  2871.     (div:QI (match_operand:HI 1 "general_operand" "0")
  2872.         (match_operand:QI 2 "general_operand" "qm")))]
  2873.   ""
  2874.   "idiv%B0 %2")
  2875.  
  2876. (define_insn "udivqi3"
  2877.   [(set (match_operand:QI 0 "general_operand" "=a")
  2878.     (udiv:QI (match_operand:HI 1 "general_operand" "0")
  2879.          (match_operand:QI 2 "general_operand" "qm")))]
  2880.   ""
  2881.   "div%B0 %2")
  2882.  
  2883. ;; The patterns that match these are at the end of this file.
  2884.  
  2885. (define_expand "divxf3"
  2886.   [(set (match_operand:XF 0 "register_operand" "")
  2887.     (div:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2888.         (match_operand:XF 2 "nonimmediate_operand" "")))]
  2889.   "TARGET_80387"
  2890.   "")
  2891.  
  2892. (define_expand "divdf3"
  2893.   [(set (match_operand:DF 0 "register_operand" "")
  2894.     (div:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2895.         (match_operand:DF 2 "nonimmediate_operand" "")))]
  2896.   "TARGET_80387"
  2897.   "")
  2898.  
  2899. (define_expand "divsf3"
  2900.   [(set (match_operand:SF 0 "register_operand" "")
  2901.     (div:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2902.         (match_operand:SF 2 "nonimmediate_operand" "")))]
  2903.   "TARGET_80387"
  2904.   "")
  2905.  
  2906. ;; Remainder instructions.
  2907.  
  2908. (define_insn "divmodsi4"
  2909.   [(set (match_operand:SI 0 "register_operand" "=a")
  2910.     (div:SI (match_operand:SI 1 "register_operand" "0")
  2911.         (match_operand:SI 2 "general_operand" "rm")))
  2912.    (set (match_operand:SI 3 "register_operand" "=&d")
  2913.     (mod:SI (match_dup 1) (match_dup 2)))]
  2914.   ""
  2915.   "*
  2916. {
  2917. #ifdef INTEL_SYNTAX
  2918.   output_asm_insn (\"cdq\", operands);
  2919. #else
  2920.   output_asm_insn (\"cltd\", operands);
  2921. #endif
  2922.   return AS1 (idiv%L0,%2);
  2923. }")
  2924.  
  2925. (define_insn "divmodhi4"
  2926.   [(set (match_operand:HI 0 "register_operand" "=a")
  2927.     (div:HI (match_operand:HI 1 "register_operand" "0")
  2928.         (match_operand:HI 2 "general_operand" "rm")))
  2929.    (set (match_operand:HI 3 "register_operand" "=&d")
  2930.     (mod:HI (match_dup 1) (match_dup 2)))]
  2931.   ""
  2932.   "cwtd\;idiv%W0 %2")
  2933.  
  2934. ;; ??? Can we make gcc zero extend operand[0]?
  2935. (define_insn "udivmodsi4"
  2936.   [(set (match_operand:SI 0 "register_operand" "=a")
  2937.     (udiv:SI (match_operand:SI 1 "register_operand" "0")
  2938.          (match_operand:SI 2 "general_operand" "rm")))
  2939.    (set (match_operand:SI 3 "register_operand" "=&d")
  2940.     (umod:SI (match_dup 1) (match_dup 2)))]
  2941.   ""
  2942.   "*
  2943. {
  2944.   output_asm_insn (AS2 (xor%L3,%3,%3), operands);
  2945.   return AS1 (div%L0,%2);
  2946. }")
  2947.  
  2948. ;; ??? Can we make gcc zero extend operand[0]?
  2949. (define_insn "udivmodhi4"
  2950.   [(set (match_operand:HI 0 "register_operand" "=a")
  2951.     (udiv:HI (match_operand:HI 1 "register_operand" "0")
  2952.          (match_operand:HI 2 "general_operand" "rm")))
  2953.    (set (match_operand:HI 3 "register_operand" "=&d")
  2954.     (umod:HI (match_dup 1) (match_dup 2)))]
  2955.   ""
  2956.   "*
  2957. {
  2958.   output_asm_insn (AS2 (xor%W0,%3,%3), operands);
  2959.   return AS1 (div%W0,%2);
  2960. }")
  2961.  
  2962. /*
  2963. ;;this should be a valid double division which we may want to add
  2964.  
  2965. (define_insn ""
  2966.   [(set (match_operand:SI 0 "register_operand" "=a")
  2967.     (udiv:DI (match_operand:DI 1 "register_operand" "a")
  2968.          (match_operand:SI 2 "general_operand" "rm")))
  2969.    (set (match_operand:SI 3 "register_operand" "=d")
  2970.     (umod:SI (match_dup 1) (match_dup 2)))]
  2971.   ""
  2972.   "div%L0 %2,%0")
  2973. */
  2974.  
  2975. ;;- and instructions
  2976.  
  2977. ;; On i386,
  2978. ;;            movzbl %bl,%ebx
  2979. ;; is faster than
  2980. ;;            andl $255,%ebx
  2981. ;;
  2982. ;; but if the reg is %eax, then the "andl" is faster.
  2983. ;;
  2984. ;; On i486, the "andl" is always faster than the "movzbl".
  2985. ;;
  2986. ;; On both i386 and i486, a three operand AND is as fast with movzbl or
  2987. ;; movzwl as with andl, if operands[0] != operands[1].
  2988.  
  2989. ;; The `r' in `rm' for operand 3 looks redundant, but it causes
  2990. ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
  2991.  
  2992. ;; ??? What if we only change one byte of an offsettable memory reference?
  2993. (define_insn "andsi3"
  2994.   [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
  2995.     (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
  2996.         (match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
  2997.   ""
  2998.   "*
  2999. {
  3000.   if (GET_CODE (operands[2]) == CONST_INT
  3001.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3002.     {
  3003.       if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
  3004.       && (! REG_P (operands[1])
  3005.           || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  3006.       && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
  3007.     {
  3008.       /* ??? tege: Should forget CC_STATUS only if we clobber a
  3009.          remembered operand.  Fix that later.  */
  3010.       CC_STATUS_INIT;
  3011. #ifdef INTEL_SYNTAX
  3012.       return AS2 (movzx,%w1,%0);
  3013. #else
  3014.       return AS2 (movz%W0%L0,%w1,%0);
  3015. #endif
  3016.     }
  3017.  
  3018.       if (INTVAL (operands[2]) == 0xff && REG_P (operands[0])
  3019.       && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
  3020.       && (! REG_P (operands[1])
  3021.           || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  3022.       && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
  3023.     {
  3024.       /* ??? tege: Should forget CC_STATUS only if we clobber a
  3025.          remembered operand.  Fix that later.  */
  3026.       CC_STATUS_INIT;
  3027. #ifdef INTEL_SYNTAX
  3028.       return AS2 (movzx,%b1,%0);
  3029. #else
  3030.       return AS2 (movz%B0%L0,%b1,%0);
  3031. #endif
  3032.     }
  3033.  
  3034.       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff) == 0)
  3035.     {
  3036.       CC_STATUS_INIT;
  3037.  
  3038.       if (INTVAL (operands[2]) == 0xffffff00)
  3039.         {
  3040.           operands[2] = const0_rtx;
  3041.           return AS2 (mov%B0,%2,%b0);
  3042.         }
  3043.  
  3044.       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  3045.       return AS2 (and%B0,%2,%b0);
  3046.     }
  3047.  
  3048.       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff00) == 0)
  3049.     {
  3050.       CC_STATUS_INIT;
  3051.  
  3052.       if (INTVAL (operands[2]) == 0xffff00ff)
  3053.         {
  3054.           operands[2] = const0_rtx;
  3055.           return AS2 (mov%B0,%2,%h0);
  3056.         }
  3057.  
  3058.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  3059.       return AS2 (and%B0,%2,%h0);
  3060.     }
  3061.  
  3062.       if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) == 0xffff0000)
  3063.         {
  3064.       operands[2] = const0_rtx;
  3065.       return AS2 (mov%W0,%2,%w0);
  3066.     }
  3067.     }
  3068.  
  3069.   return AS2 (and%L0,%2,%0);
  3070. }")
  3071.  
  3072. (define_insn "andhi3"
  3073.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  3074.     (and:HI (match_operand:HI 1 "general_operand" "%0,0")
  3075.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  3076.   ""
  3077.   "*
  3078. {
  3079.   if (GET_CODE (operands[2]) == CONST_INT
  3080.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3081.     {
  3082.       /* Can we ignore the upper byte? */
  3083.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3084.       && (INTVAL (operands[2]) & 0xff00) == 0xff00)
  3085.     {
  3086.       CC_STATUS_INIT;
  3087.  
  3088.       if ((INTVAL (operands[2]) & 0xff) == 0)
  3089.         {
  3090.           operands[2] = const0_rtx;
  3091.           return AS2 (mov%B0,%2,%b0);
  3092.         }
  3093.  
  3094.       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  3095.       return AS2 (and%B0,%2,%b0);
  3096.     }
  3097.  
  3098.       /* Can we ignore the lower byte? */
  3099.       /* ??? what about offsettable memory references? */
  3100.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
  3101.     {
  3102.       CC_STATUS_INIT;
  3103.  
  3104.       if ((INTVAL (operands[2]) & 0xff00) == 0)
  3105.         {
  3106.           operands[2] = const0_rtx;
  3107.           return AS2 (mov%B0,%2,%h0);
  3108.         }
  3109.  
  3110.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  3111.       return AS2 (and%B0,%2,%h0);
  3112.     }
  3113.     }
  3114.  
  3115.   return AS2 (and%W0,%2,%0);
  3116. }")
  3117.  
  3118. (define_insn "andqi3"
  3119.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  3120.     (and:QI (match_operand:QI 1 "general_operand" "%0,0")
  3121.         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  3122.   ""
  3123.   "* return AS2 (and%B0,%2,%0);")
  3124.  
  3125. /* I am nervous about these two.. add them later..
  3126. ;I presume this means that we have something in say op0= eax which is small
  3127. ;and we want to and it with memory so we can do this by just an
  3128. ;andb m,%al  and have success.
  3129. (define_insn ""
  3130.   [(set (match_operand:SI 0 "general_operand" "=r")
  3131.     (and:SI (zero_extend:SI
  3132.          (match_operand:HI 1 "nonimmediate_operand" "rm"))
  3133.         (match_operand:SI 2 "general_operand" "0")))]
  3134.   "GET_CODE (operands[2]) == CONST_INT
  3135.    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
  3136.   "and%W0 %1,%0")
  3137.  
  3138. (define_insn ""
  3139.   [(set (match_operand:SI 0 "general_operand" "=q")
  3140.     (and:SI
  3141.      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
  3142.         (match_operand:SI 2 "general_operand" "0")))]
  3143.   "GET_CODE (operands[2]) == CONST_INT
  3144.    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
  3145.   "and%L0 %1,%0")
  3146.  
  3147. */
  3148.  
  3149. ;;- Bit set (inclusive or) instructions
  3150.  
  3151. ;; ??? What if we only change one byte of an offsettable memory reference?
  3152. (define_insn "iorsi3"
  3153.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  3154.     (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
  3155.         (match_operand:SI 2 "general_operand" "ri,rm")))]
  3156.   ""
  3157.   "*
  3158. {
  3159.   if (GET_CODE (operands[2]) == CONST_INT
  3160.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3161.     {
  3162.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3163.       && (INTVAL (operands[2]) & ~0xff) == 0)
  3164.     {
  3165.       CC_STATUS_INIT;
  3166.  
  3167.       if (INTVAL (operands[2]) == 0xff)
  3168.         return AS2 (mov%B0,%2,%b0);
  3169.  
  3170.       return AS2 (or%B0,%2,%b0);
  3171.     }
  3172.  
  3173.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
  3174.     {
  3175.       CC_STATUS_INIT;
  3176.       operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
  3177.  
  3178.       if (INTVAL (operands[2]) == 0xff)
  3179.         return AS2 (mov%B0,%2,%h0);
  3180.  
  3181.       return AS2 (or%B0,%2,%h0);
  3182.     }
  3183.     }
  3184.  
  3185.   return AS2 (or%L0,%2,%0);
  3186. }")
  3187.  
  3188. (define_insn "iorhi3"
  3189.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  3190.     (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
  3191.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  3192.   ""
  3193.   "*
  3194. {
  3195.   if (GET_CODE (operands[2]) == CONST_INT
  3196.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3197.     {
  3198.       /* Can we ignore the upper byte? */
  3199.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3200.       && (INTVAL (operands[2]) & 0xff00) == 0)
  3201.     {
  3202.       CC_STATUS_INIT;
  3203.       if (INTVAL (operands[2]) & 0xffff0000)
  3204.         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
  3205.  
  3206.       if (INTVAL (operands[2]) == 0xff)
  3207.         return AS2 (mov%B0,%2,%b0);
  3208.  
  3209.       return AS2 (or%B0,%2,%b0);
  3210.     }
  3211.  
  3212.       /* Can we ignore the lower byte? */
  3213.       /* ??? what about offsettable memory references? */
  3214.       if (QI_REG_P (operands[0])
  3215.       && (INTVAL (operands[2]) & 0xff) == 0)
  3216.     {
  3217.       CC_STATUS_INIT;
  3218.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  3219.  
  3220.       if (INTVAL (operands[2]) == 0xff)
  3221.         return AS2 (mov%B0,%2,%h0);
  3222.  
  3223.       return AS2 (or%B0,%2,%h0);
  3224.     }
  3225.     }
  3226.  
  3227.   return AS2 (or%W0,%2,%0);
  3228. }")
  3229.  
  3230. (define_insn "iorqi3"
  3231.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  3232.     (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
  3233.         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  3234.   ""
  3235.   "* return AS2 (or%B0,%2,%0);")
  3236.  
  3237. ;;- xor instructions
  3238.  
  3239. ;; ??? What if we only change one byte of an offsettable memory reference?
  3240. (define_insn "xorsi3"
  3241.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  3242.     (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
  3243.         (match_operand:SI 2 "general_operand" "ri,rm")))]
  3244.   ""
  3245.   "*
  3246. {
  3247.   if (GET_CODE (operands[2]) == CONST_INT
  3248.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3249.     {
  3250.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3251.       && (INTVAL (operands[2]) & ~0xff) == 0)
  3252.     {
  3253.       CC_STATUS_INIT;
  3254.  
  3255.       if (INTVAL (operands[2]) == 0xff)
  3256.         return AS1 (not%B0,%b0);
  3257.  
  3258.       return AS2 (xor%B0,%2,%b0);
  3259.     }
  3260.  
  3261.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
  3262.     {
  3263.       CC_STATUS_INIT;
  3264.       operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
  3265.  
  3266.       if (INTVAL (operands[2]) == 0xff)
  3267.         return AS1 (not%B0,%h0);
  3268.  
  3269.       return AS2 (xor%B0,%2,%h0);
  3270.     }
  3271.     }
  3272.  
  3273.   return AS2 (xor%L0,%2,%0);
  3274. }")
  3275.  
  3276. (define_insn "xorhi3"
  3277.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  3278.     (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
  3279.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  3280.   ""
  3281.   "*
  3282. {
  3283.   if (GET_CODE (operands[2]) == CONST_INT
  3284.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  3285.     {
  3286.       /* Can we ignore the upper byte? */
  3287.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3288.       && (INTVAL (operands[2]) & 0xff00) == 0)
  3289.     {
  3290.       CC_STATUS_INIT;
  3291.       if (INTVAL (operands[2]) & 0xffff0000)
  3292.         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
  3293.  
  3294.       if (INTVAL (operands[2]) == 0xff)
  3295.         return AS1 (not%B0,%b0);
  3296.  
  3297.       return AS2 (xor%B0,%2,%b0);
  3298.     }
  3299.  
  3300.       /* Can we ignore the lower byte? */
  3301.       /* ??? what about offsettable memory references? */
  3302.       if (QI_REG_P (operands[0])
  3303.       && (INTVAL (operands[2]) & 0xff) == 0)
  3304.     {
  3305.       CC_STATUS_INIT;
  3306.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  3307.  
  3308.       if (INTVAL (operands[2]) == 0xff)
  3309.         return AS1 (not%B0,%h0);
  3310.  
  3311.       return AS2 (xor%B0,%2,%h0);
  3312.     }
  3313.     }
  3314.  
  3315.   return AS2 (xor%W0,%2,%0);
  3316. }")
  3317.  
  3318. (define_insn "xorqi3"
  3319.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  3320.     (xor:QI (match_operand:QI 1 "general_operand" "%0,0")
  3321.         (match_operand:QI 2 "general_operand" "qn,qm")))]
  3322.   ""
  3323.   "* return AS2 (xor%B0,%2,%0);")
  3324.  
  3325. ;;- negation instructions
  3326.  
  3327. (define_insn "negdi2"
  3328.   [(set (match_operand:DI 0 "general_operand" "=&ro")
  3329.     (neg:DI (match_operand:DI 1 "general_operand" "0")))]
  3330.   ""
  3331.   "*
  3332. {
  3333.   rtx xops[2], low[1], high[1];
  3334.  
  3335.   CC_STATUS_INIT;
  3336.  
  3337.   split_di (operands, 1, low, high);
  3338.   xops[0] = const0_rtx;
  3339.   xops[1] = high[0];
  3340.  
  3341.   output_asm_insn (AS1 (neg%L0,%0), low);
  3342.   output_asm_insn (AS2 (adc%L1,%0,%1), xops);
  3343.   output_asm_insn (AS1 (neg%L0,%0), high);
  3344.   RET;
  3345. }")
  3346.  
  3347. (define_insn "negsi2"
  3348.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3349.     (neg:SI (match_operand:SI 1 "general_operand" "0")))]
  3350.   ""
  3351.   "neg%L0 %0")
  3352.  
  3353. (define_insn "neghi2"
  3354.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3355.     (neg:HI (match_operand:HI 1 "general_operand" "0")))]
  3356.   ""
  3357.   "neg%W0 %0")
  3358.  
  3359. (define_insn "negqi2"
  3360.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3361.     (neg:QI (match_operand:QI 1 "general_operand" "0")))]
  3362.   ""
  3363.   "neg%B0 %0")
  3364.  
  3365. (define_insn "negsf2"
  3366.   [(set (match_operand:SF 0 "register_operand" "=f")
  3367.     (neg:SF (match_operand:SF 1 "general_operand" "0")))]
  3368.   "TARGET_80387"
  3369.   "fchs")
  3370.  
  3371. (define_insn "negdf2"
  3372.   [(set (match_operand:DF 0 "register_operand" "=f")
  3373.     (neg:DF (match_operand:DF 1 "general_operand" "0")))]
  3374.   "TARGET_80387"
  3375.   "fchs")
  3376.  
  3377. (define_insn ""
  3378.   [(set (match_operand:DF 0 "register_operand" "=f")
  3379.     (neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  3380.   "TARGET_80387"
  3381.   "fchs")
  3382.  
  3383. (define_insn "negxf2"
  3384.   [(set (match_operand:XF 0 "register_operand" "=f")
  3385.     (neg:XF (match_operand:XF 1 "general_operand" "0")))]
  3386.   "TARGET_80387"
  3387.   "fchs")
  3388.  
  3389. (define_insn ""
  3390.   [(set (match_operand:XF 0 "register_operand" "=f")
  3391.     (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  3392.   "TARGET_80387"
  3393.   "fchs")
  3394.  
  3395. ;; Absolute value instructions
  3396.  
  3397. (define_insn "abssf2"
  3398.   [(set (match_operand:SF 0 "register_operand" "=f")
  3399.     (abs:SF (match_operand:SF 1 "general_operand" "0")))]
  3400.   "TARGET_80387"
  3401.   "fabs")
  3402.  
  3403. (define_insn "absdf2"
  3404.   [(set (match_operand:DF 0 "register_operand" "=f")
  3405.     (abs:DF (match_operand:DF 1 "general_operand" "0")))]
  3406.   "TARGET_80387"
  3407.   "fabs")
  3408.  
  3409. (define_insn ""
  3410.   [(set (match_operand:DF 0 "register_operand" "=f")
  3411.     (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  3412.   "TARGET_80387"
  3413.   "fabs")
  3414.  
  3415. (define_insn "absxf2"
  3416.   [(set (match_operand:XF 0 "register_operand" "=f")
  3417.     (abs:XF (match_operand:XF 1 "general_operand" "0")))]
  3418.   "TARGET_80387"
  3419.   "fabs")
  3420.  
  3421. (define_insn ""
  3422.   [(set (match_operand:XF 0 "register_operand" "=f")
  3423.     (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  3424.   "TARGET_80387"
  3425.   "fabs")
  3426.  
  3427. (define_insn "sqrtsf2"
  3428.   [(set (match_operand:SF 0 "register_operand" "=f")
  3429.     (sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
  3430.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
  3431.    && (TARGET_IEEE_FP || flag_fast_math) "
  3432.   "fsqrt")
  3433.  
  3434. (define_insn "sqrtdf2"
  3435.   [(set (match_operand:DF 0 "register_operand" "=f")
  3436.     (sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
  3437.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
  3438.    && (TARGET_IEEE_FP || flag_fast_math) "
  3439.   "fsqrt")
  3440.  
  3441. (define_insn ""
  3442.   [(set (match_operand:DF 0 "register_operand" "=f")
  3443.     (sqrt:DF (float_extend:DF
  3444.           (match_operand:SF 1 "general_operand" "0"))))]
  3445.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3446.    && (TARGET_IEEE_FP || flag_fast_math) "
  3447.   "fsqrt")
  3448.  
  3449. (define_insn "sqrtxf2"
  3450.   [(set (match_operand:XF 0 "register_operand" "=f")
  3451.     (sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
  3452.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3453.    && (TARGET_IEEE_FP || flag_fast_math) "
  3454.   "fsqrt")
  3455.  
  3456. (define_insn ""
  3457.   [(set (match_operand:XF 0 "register_operand" "=f")
  3458.     (sqrt:XF (float_extend:XF
  3459.           (match_operand:DF 1 "general_operand" "0"))))]
  3460.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3461.    && (TARGET_IEEE_FP || flag_fast_math) "
  3462.   "fsqrt")
  3463.  
  3464. (define_insn ""
  3465.   [(set (match_operand:XF 0 "register_operand" "=f")
  3466.     (sqrt:XF (float_extend:XF
  3467.           (match_operand:SF 1 "general_operand" "0"))))]
  3468.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3469.    && (TARGET_IEEE_FP || flag_fast_math) "
  3470.   "fsqrt")
  3471.  
  3472. (define_insn "sindf2"
  3473.   [(set (match_operand:DF 0 "register_operand" "=f")
  3474.     (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
  3475.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3476.    && (TARGET_IEEE_FP || flag_fast_math) "
  3477.   "fsin")
  3478.  
  3479. (define_insn "sinsf2"
  3480.   [(set (match_operand:SF 0 "register_operand" "=f")
  3481.     (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
  3482.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3483.    && (TARGET_IEEE_FP || flag_fast_math) "
  3484.   "fsin")
  3485.  
  3486. (define_insn ""
  3487.   [(set (match_operand:DF 0 "register_operand" "=f")
  3488.     (unspec:DF [(float_extend:DF
  3489.              (match_operand:SF 1 "register_operand" "0"))] 1))]
  3490.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3491.    && (TARGET_IEEE_FP || flag_fast_math) "
  3492.   "fsin")
  3493.  
  3494. (define_insn "sinxf2"
  3495.   [(set (match_operand:XF 0 "register_operand" "=f")
  3496.     (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
  3497.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3498.    && (TARGET_IEEE_FP || flag_fast_math) "
  3499.   "fsin")
  3500.  
  3501. (define_insn "cosdf2"
  3502.   [(set (match_operand:DF 0 "register_operand" "=f")
  3503.     (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
  3504.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3505.    && (TARGET_IEEE_FP || flag_fast_math) "
  3506.   "fcos")
  3507.  
  3508. (define_insn "cossf2"
  3509.   [(set (match_operand:SF 0 "register_operand" "=f")
  3510.     (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
  3511.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3512.    && (TARGET_IEEE_FP || flag_fast_math) "
  3513.   "fcos")
  3514.  
  3515. (define_insn ""
  3516.   [(set (match_operand:DF 0 "register_operand" "=f")
  3517.     (unspec:DF [(float_extend:DF
  3518.              (match_operand:SF 1 "register_operand" "0"))] 2))]
  3519.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3520.    && (TARGET_IEEE_FP || flag_fast_math) "
  3521.   "fcos")
  3522.  
  3523. (define_insn "cosxf2"
  3524.   [(set (match_operand:XF 0 "register_operand" "=f")
  3525.     (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
  3526.   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
  3527.    && (TARGET_IEEE_FP || flag_fast_math) "
  3528.   "fcos")
  3529.  
  3530. ;;- one complement instructions
  3531.  
  3532. (define_insn "one_cmplsi2"
  3533.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3534.     (not:SI (match_operand:SI 1 "general_operand" "0")))]
  3535.   ""
  3536.   "not%L0 %0")
  3537.  
  3538. (define_insn "one_cmplhi2"
  3539.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3540.     (not:HI (match_operand:HI 1 "general_operand" "0")))]
  3541.   ""
  3542.   "not%W0 %0")
  3543.  
  3544. (define_insn "one_cmplqi2"
  3545.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3546.     (not:QI (match_operand:QI 1 "general_operand" "0")))]
  3547.   ""
  3548.   "not%B0 %0")
  3549.  
  3550. ;;- arithmetic shift instructions
  3551.  
  3552. ;; DImode shifts are implemented using the i386 "shift double" opcode,
  3553. ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
  3554. ;; is variable, then the count is in %cl and the "imm" operand is dropped
  3555. ;; from the assembler input.
  3556.  
  3557. ;; This instruction shifts the target reg/mem as usual, but instead of
  3558. ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
  3559. ;; is a left shift double, bits are taken from the high order bits of
  3560. ;; reg, else if the insn is a shift right double, bits are taken from the
  3561. ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
  3562. ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
  3563.  
  3564. ;; Since sh[lr]d does not change the `reg' operand, that is done
  3565. ;; separately, making all shifts emit pairs of shift double and normal
  3566. ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
  3567. ;; support a 63 bit shift, each shift where the count is in a reg expands
  3568. ;; to three pairs.  If the overall shift is by N bits, then the first two
  3569. ;; pairs shift by N / 2 and the last pair by N & 1.
  3570.  
  3571. ;; If the shift count is a constant, we need never emit more than one
  3572. ;; shift pair, instead using moves and sign extension for counts greater
  3573. ;; than 31.
  3574.  
  3575. (define_expand "ashldi3"
  3576.   [(set (match_operand:DI 0 "register_operand" "")
  3577.     (ashift:DI (match_operand:DI 1 "register_operand" "")
  3578.            (match_operand:QI 2 "nonmemory_operand" "")))]
  3579.   ""
  3580.   "
  3581. {
  3582.   if (GET_CODE (operands[2]) != CONST_INT
  3583.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3584.     {
  3585.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3586.       emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
  3587.                         operands[2]));
  3588.     }
  3589.   else
  3590.     emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
  3591.  
  3592.   DONE;
  3593. }")
  3594.  
  3595. (define_insn "ashldi3_const_int"
  3596.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3597.     (ashift:DI (match_operand:DI 1 "register_operand" "0")
  3598.            (match_operand:QI 2 "const_int_operand" "J")))]
  3599.   ""
  3600.   "*
  3601. {
  3602.   rtx xops[4], low[1], high[1];
  3603.  
  3604.   CC_STATUS_INIT;
  3605.  
  3606.   split_di (operands, 1, low, high);
  3607.   xops[0] = operands[2];
  3608.   xops[1] = const1_rtx;
  3609.   xops[2] = low[0];
  3610.   xops[3] = high[0];
  3611.  
  3612.   if (INTVAL (xops[0]) > 31)
  3613.     {
  3614.       output_asm_insn (AS2 (mov%L3,%2,%3), xops);    /* Fast shift by 32 */
  3615.       output_asm_insn (AS2 (xor%L2,%2,%2), xops);
  3616.  
  3617.       if (INTVAL (xops[0]) > 32)
  3618.         {
  3619.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3620.       output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
  3621.     }
  3622.     }
  3623.   else
  3624.     {
  3625.       output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
  3626.       output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3627.     }
  3628.   RET;
  3629. }")
  3630.  
  3631. (define_insn "ashldi3_non_const_int"
  3632.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3633.     (ashift:DI (match_operand:DI 1 "register_operand" "0")
  3634.            (match_operand:QI 2 "register_operand" "c")))
  3635.    (clobber (match_dup 2))]
  3636.   ""
  3637.   "*
  3638. {
  3639.   rtx xops[4], low[1], high[1];
  3640.  
  3641.   CC_STATUS_INIT;
  3642.  
  3643.   split_di (operands, 1, low, high);
  3644.   xops[0] = operands[2];
  3645.   xops[1] = const1_rtx;
  3646.   xops[2] = low[0];
  3647.   xops[3] = high[0];
  3648.  
  3649.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3650.  
  3651.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3652.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3653.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3654.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3655.  
  3656.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3657.  
  3658.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3659.  
  3660.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3661.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3662.  
  3663.   RET;
  3664. }")
  3665.  
  3666. ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
  3667. ;; On i486, movl/sall appears slightly faster than leal, but the leal
  3668. ;; is smaller - use leal for now unless the shift count is 1.
  3669.  
  3670. (define_insn "ashlsi3"
  3671.   [(set (match_operand:SI 0 "general_operand" "=r,rm")
  3672.     (ashift:SI (match_operand:SI 1 "general_operand" "r,0")
  3673.            (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
  3674.   ""
  3675.   "*
  3676. {
  3677.   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  3678.     {
  3679.       if (!TARGET_386 && INTVAL (operands[2]) == 1)
  3680.     {
  3681.       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  3682.       return AS2 (add%L0,%1,%0);
  3683.     }
  3684.       else
  3685.         {
  3686.           CC_STATUS_INIT;
  3687.  
  3688.       if (operands[1] == stack_pointer_rtx)
  3689.         {
  3690.           output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  3691.           operands[1] = operands[0];
  3692.         }
  3693.           operands[1] = gen_rtx (MULT, SImode, operands[1],
  3694.                  GEN_INT (1 << INTVAL (operands[2])));
  3695.       return AS2 (lea%L0,%a1,%0);
  3696.     }
  3697.     }
  3698.  
  3699.   if (REG_P (operands[2]))
  3700.     return AS2 (sal%L0,%b2,%0);
  3701.  
  3702.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3703.     return AS2 (add%L0,%0,%0);
  3704.  
  3705.   return AS2 (sal%L0,%2,%0);
  3706. }")
  3707.  
  3708. (define_insn "ashlhi3"
  3709.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3710.     (ashift:HI (match_operand:HI 1 "general_operand" "0")
  3711.            (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3712.   ""
  3713.   "*
  3714. {
  3715.   if (REG_P (operands[2]))
  3716.     return AS2 (sal%W0,%b2,%0);
  3717.  
  3718.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3719.     return AS2 (add%W0,%0,%0);
  3720.  
  3721.   return AS2 (sal%W0,%2,%0);
  3722. }")
  3723.  
  3724. (define_insn "ashlqi3"
  3725.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3726.     (ashift:QI (match_operand:QI 1 "general_operand" "0")
  3727.            (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3728.   ""
  3729.   "*
  3730. {
  3731.   if (REG_P (operands[2]))
  3732.     return AS2 (sal%B0,%b2,%0);
  3733.  
  3734.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3735.     return AS2 (add%B0,%0,%0);
  3736.  
  3737.   return AS2 (sal%B0,%2,%0);
  3738. }")
  3739.  
  3740. ;; See comment above `ashldi3' about how this works.
  3741.  
  3742. (define_expand "ashrdi3"
  3743.   [(set (match_operand:DI 0 "register_operand" "")
  3744.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
  3745.              (match_operand:QI 2 "nonmemory_operand" "")))]
  3746.   ""
  3747.   "
  3748. {
  3749.   if (GET_CODE (operands[2]) != CONST_INT
  3750.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3751.     {
  3752.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3753.       emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
  3754.                         operands[2]));
  3755.     }
  3756.   else
  3757.     emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
  3758.  
  3759.   DONE;
  3760. }")
  3761.  
  3762. (define_insn "ashrdi3_const_int"
  3763.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3764.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3765.              (match_operand:QI 2 "const_int_operand" "J")))]
  3766.   ""
  3767.   "*
  3768. {
  3769.   rtx xops[4], low[1], high[1];
  3770.  
  3771.   CC_STATUS_INIT;
  3772.  
  3773.   split_di (operands, 1, low, high);
  3774.   xops[0] = operands[2];
  3775.   xops[1] = const1_rtx;
  3776.   xops[2] = low[0];
  3777.   xops[3] = high[0];
  3778.  
  3779.   if (INTVAL (xops[0]) > 31)
  3780.     {
  3781.       xops[1] = GEN_INT (31);
  3782.       output_asm_insn (AS2 (mov%L2,%3,%2), xops);
  3783.       output_asm_insn (AS2 (sar%L3,%1,%3), xops);    /* shift by 32 */
  3784.  
  3785.       if (INTVAL (xops[0]) > 32)
  3786.         {
  3787.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3788.       output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
  3789.     }
  3790.     }
  3791.   else
  3792.     {
  3793.       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
  3794.       output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3795.     }
  3796.  
  3797.   RET;
  3798. }")
  3799.  
  3800. (define_insn "ashrdi3_non_const_int"
  3801.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3802.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3803.              (match_operand:QI 2 "register_operand" "c")))
  3804.    (clobber (match_dup 2))]
  3805.   ""
  3806.   "*
  3807. {
  3808.   rtx xops[4], low[1], high[1];
  3809.  
  3810.   CC_STATUS_INIT;
  3811.  
  3812.   split_di (operands, 1, low, high);
  3813.   xops[0] = operands[2];
  3814.   xops[1] = const1_rtx;
  3815.   xops[2] = low[0];
  3816.   xops[3] = high[0];
  3817.  
  3818.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3819.  
  3820.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3821.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3822.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3823.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3824.  
  3825.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3826.  
  3827.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3828.  
  3829.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3830.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3831.  
  3832.   RET;
  3833. }")
  3834.  
  3835. (define_insn "ashrsi3"
  3836.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3837.     (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
  3838.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3839.   ""
  3840.   "*
  3841. {
  3842.   if (REG_P (operands[2]))
  3843.     return AS2 (sar%L0,%b2,%0);
  3844.   else
  3845.     return AS2 (sar%L0,%2,%0);
  3846. }")
  3847.  
  3848. (define_insn "ashrhi3"
  3849.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3850.     (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
  3851.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3852.   ""
  3853.   "*
  3854. {
  3855.   if (REG_P (operands[2]))
  3856.     return AS2 (sar%W0,%b2,%0);
  3857.   else
  3858.     return AS2 (sar%W0,%2,%0);
  3859. }")
  3860.  
  3861. (define_insn "ashrqi3"
  3862.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3863.     (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
  3864.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3865.   ""
  3866.   "*
  3867. {
  3868.   if (REG_P (operands[2]))
  3869.     return AS2 (sar%B0,%b2,%0);
  3870.   else
  3871.     return AS2 (sar%B0,%2,%0);
  3872. }")
  3873.  
  3874. ;;- logical shift instructions
  3875.  
  3876. ;; See comment above `ashldi3' about how this works.
  3877.  
  3878. (define_expand "lshrdi3"
  3879.   [(set (match_operand:DI 0 "register_operand" "")
  3880.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
  3881.              (match_operand:QI 2 "nonmemory_operand" "")))]
  3882.   ""
  3883.   "
  3884. {
  3885.   if (GET_CODE (operands[2]) != CONST_INT
  3886.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3887.     {
  3888.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3889.       emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
  3890.                         operands[2]));
  3891.     }
  3892.   else
  3893.     emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
  3894.  
  3895.   DONE;
  3896. }")
  3897.  
  3898. (define_insn "lshrdi3_const_int"
  3899.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3900.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3901.              (match_operand:QI 2 "const_int_operand" "J")))]
  3902.   ""
  3903.   "*
  3904. {
  3905.   rtx xops[4], low[1], high[1];
  3906.  
  3907.   CC_STATUS_INIT;
  3908.  
  3909.   split_di (operands, 1, low, high);
  3910.   xops[0] = operands[2];
  3911.   xops[1] = const1_rtx;
  3912.   xops[2] = low[0];
  3913.   xops[3] = high[0];
  3914.  
  3915.   if (INTVAL (xops[0]) > 31)
  3916.     {
  3917.       output_asm_insn (AS2 (mov%L2,%3,%2), xops);    /* Fast shift by 32 */
  3918.       output_asm_insn (AS2 (xor%L3,%3,%3), xops);
  3919.  
  3920.       if (INTVAL (xops[0]) > 32)
  3921.         {
  3922.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3923.       output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
  3924.     }
  3925.     }
  3926.   else
  3927.     {
  3928.       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
  3929.       output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3930.     }
  3931.  
  3932.   RET;
  3933. }")
  3934.  
  3935. (define_insn "lshrdi3_non_const_int"
  3936.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3937.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3938.              (match_operand:QI 2 "register_operand" "c")))
  3939.    (clobber (match_dup 2))]
  3940.   ""
  3941.   "*
  3942. {
  3943.   rtx xops[4], low[1], high[1];
  3944.  
  3945.   CC_STATUS_INIT;
  3946.  
  3947.   split_di (operands, 1, low, high);
  3948.   xops[0] = operands[2];
  3949.   xops[1] = const1_rtx;
  3950.   xops[2] = low[0];
  3951.   xops[3] = high[0];
  3952.  
  3953.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3954.  
  3955.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3956.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3957.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3958.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3959.  
  3960.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3961.  
  3962.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3963.  
  3964.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3965.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3966.  
  3967.   RET;
  3968. }")
  3969.  
  3970. (define_insn "lshrsi3"
  3971.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3972.     (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
  3973.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3974.   ""
  3975.   "*
  3976. {
  3977.   if (REG_P (operands[2]))
  3978.     return AS2 (shr%L0,%b2,%0);
  3979.   else
  3980.     return AS2 (shr%L0,%2,%1);
  3981. }")
  3982.  
  3983. (define_insn "lshrhi3"
  3984.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3985.     (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
  3986.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3987.   ""
  3988.   "*
  3989. {
  3990.   if (REG_P (operands[2]))
  3991.     return AS2 (shr%W0,%b2,%0);
  3992.   else
  3993.     return AS2 (shr%W0,%2,%0);
  3994. }")
  3995.  
  3996. (define_insn "lshrqi3"
  3997.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3998.     (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
  3999.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  4000.   ""
  4001.   "*
  4002. {
  4003.   if (REG_P (operands[2]))
  4004.     return AS2 (shr%B0,%b2,%0);
  4005.   else
  4006.     return AS2 (shr%B0,%2,%0);
  4007. }")
  4008.  
  4009. ;;- rotate instructions
  4010.  
  4011. (define_insn "rotlsi3"
  4012.   [(set (match_operand:SI 0 "general_operand" "=rm")
  4013.     (rotate:SI (match_operand:SI 1 "general_operand" "0")
  4014.            (match_operand:SI 2 "nonmemory_operand" "cI")))]
  4015.   ""
  4016.   "*
  4017. {
  4018.   if (REG_P (operands[2]))
  4019.     return AS2 (rol%L0,%b2,%0);
  4020.   else
  4021.     return AS2 (rol%L0,%2,%0);
  4022. }")
  4023.  
  4024. (define_insn "rotlhi3"
  4025.   [(set (match_operand:HI 0 "general_operand" "=rm")
  4026.     (rotate:HI (match_operand:HI 1 "general_operand" "0")
  4027.            (match_operand:HI 2 "nonmemory_operand" "cI")))]
  4028.   ""
  4029.   "*
  4030. {
  4031.   if (REG_P (operands[2]))
  4032.     return AS2 (rol%W0,%b2,%0);
  4033.   else
  4034.     return AS2 (rol%W0,%2,%0);
  4035. }")
  4036.  
  4037. (define_insn "rotlqi3"
  4038.   [(set (match_operand:QI 0 "general_operand" "=qm")
  4039.     (rotate:QI (match_operand:QI 1 "general_operand" "0")
  4040.            (match_operand:QI 2 "nonmemory_operand" "cI")))]
  4041.   ""
  4042.   "*
  4043. {
  4044.   if (REG_P (operands[2]))
  4045.     return AS2 (rol%B0,%b2,%0);
  4046.   else
  4047.     return AS2 (rol%B0,%2,%0);
  4048. }")
  4049.  
  4050. (define_insn "rotrsi3"
  4051.   [(set (match_operand:SI 0 "general_operand" "=rm")
  4052.     (rotatert:SI (match_operand:SI 1 "general_operand" "0")
  4053.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  4054.   ""
  4055.   "*
  4056. {
  4057.   if (REG_P (operands[2]))
  4058.     return AS2 (ror%L0,%b2,%0);
  4059.   else
  4060.     return AS2 (ror%L0,%2,%0);
  4061. }")
  4062.  
  4063. (define_insn "rotrhi3"
  4064.   [(set (match_operand:HI 0 "general_operand" "=rm")
  4065.     (rotatert:HI (match_operand:HI 1 "general_operand" "0")
  4066.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  4067.   ""
  4068.   "*
  4069. {
  4070.   if (REG_P (operands[2]))
  4071.     return AS2 (ror%W0,%b2,%0);
  4072.   else
  4073.     return AS2 (ror%W0,%2,%0);
  4074. }")
  4075.  
  4076. (define_insn "rotrqi3"
  4077.   [(set (match_operand:QI 0 "general_operand" "=qm")
  4078.     (rotatert:QI (match_operand:QI 1 "general_operand" "0")
  4079.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  4080.   ""
  4081.   "*
  4082. {
  4083.   if (REG_P (operands[2]))
  4084.     return AS2 (ror%B0,%b2,%0);
  4085.   else
  4086.     return AS2 (ror%B0,%2,%0);
  4087. }")
  4088.  
  4089. /*
  4090. ;; This usually looses.  But try a define_expand to recognize a few case
  4091. ;; we can do efficiently, such as accessing the "high" QImode registers,
  4092. ;; %ah, %bh, %ch, %dh.
  4093. (define_insn "insv"
  4094.   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
  4095.              (match_operand:SI 1 "general_operand" "i")
  4096.              (match_operand:SI 2 "general_operand" "i"))
  4097.     (match_operand:SI 3 "general_operand" "ri"))]
  4098.   ""
  4099.   "*
  4100. {
  4101.   if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
  4102.     abort ();
  4103.   if (GET_CODE (operands[3]) == CONST_INT)
  4104.     {
  4105.       unsigned int mask = (1 << INTVAL (operands[1])) - 1; 
  4106.       operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
  4107.       output_asm_insn (AS2 (and%L0,%1,%0), operands);
  4108.       operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
  4109.       output_asm_insn (AS2 (or%L0,%3,%0), operands);
  4110.     }
  4111.   else
  4112.     {
  4113.       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  4114.       if (INTVAL (operands[2]))
  4115.     output_asm_insn (AS2 (ror%L0,%2,%0), operands);
  4116.       output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
  4117.       operands[2] = GEN_INT (BITS_PER_WORD
  4118.                  - INTVAL (operands[1]) - INTVAL (operands[2]));
  4119.       if (INTVAL (operands[2]))
  4120.     output_asm_insn (AS2 (ror%L0,%2,%0), operands);
  4121.     }
  4122.   RET;
  4123. }")
  4124. */
  4125. /*
  4126. ;; ??? There are problems with the mode of operand[3].  The point of this
  4127. ;; is to represent an HImode move to a "high byte" register.
  4128.  
  4129. (define_expand "insv"
  4130.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
  4131.              (match_operand:SI 1 "immediate_operand" "")
  4132.              (match_operand:SI 2 "immediate_operand" ""))
  4133.     (match_operand:QI 3 "general_operand" "ri"))]
  4134.   ""
  4135.   "
  4136. {
  4137.   if (GET_CODE (operands[1]) != CONST_INT
  4138.       || GET_CODE (operands[2]) != CONST_INT)
  4139.     FAIL;
  4140.  
  4141.   if (! (INTVAL (operands[1]) == 8
  4142.      && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
  4143.       && ! INTVAL (operands[1]) == 1)
  4144.     FAIL;
  4145. }")
  4146.  
  4147. ;; ??? Are these constraints right?
  4148. (define_insn ""
  4149.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+&qo")
  4150.              (const_int 8)
  4151.              (const_int 8))
  4152.     (match_operand:QI 1 "general_operand" "qn"))]
  4153.   ""
  4154.   "*
  4155. {
  4156.   if (REG_P (operands[0]))
  4157.     return AS2 (mov%B0,%1,%h0);
  4158.  
  4159.   operands[0] = adj_offsettable_operand (operands[0], 1);
  4160.   return AS2 (mov%B0,%1,%0);
  4161. }")
  4162. */
  4163.  
  4164. ;; On i386, the register count for a bit operation is *not* truncated,
  4165. ;; so SHIFT_COUNT_TRUNCATED must not be defined.
  4166.  
  4167. ;; On i486, the shift & or/and code is faster than bts or btr.  If
  4168. ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
  4169.  
  4170. ;; On i386, bts is a little faster if operands[0] is a reg, and a
  4171. ;; little slower if operands[0] is a MEM, than the shift & or/and code.
  4172. ;; Use bts & btr, since they reload better.
  4173.  
  4174. ;; General bit set and clear.
  4175. (define_insn ""
  4176.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+rm")
  4177.              (const_int 1)
  4178.              (match_operand:SI 2 "general_operand" "r"))
  4179.     (match_operand:SI 3 "const_int_operand" "n"))]
  4180.   "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
  4181.   "*
  4182. {
  4183.   CC_STATUS_INIT;
  4184.  
  4185.   if (INTVAL (operands[3]) == 1)
  4186.     return AS2 (bts%L0,%2,%0);
  4187.   else
  4188.     return AS2 (btr%L0,%2,%0);
  4189. }")
  4190.  
  4191. ;; Bit complement.  See comments on previous pattern.
  4192. ;; ??? Is this really worthwhile?
  4193. (define_insn ""
  4194.   [(set (match_operand:SI 0 "general_operand" "=rm")
  4195.     (xor:SI (ashift:SI (const_int 1)
  4196.                (match_operand:SI 1 "general_operand" "r"))
  4197.         (match_operand:SI 2 "general_operand" "0")))]
  4198.   "TARGET_386 && GET_CODE (operands[1]) != CONST_INT"
  4199.   "*
  4200. {
  4201.   CC_STATUS_INIT;
  4202.  
  4203.   return AS2 (btc%L0,%1,%0);
  4204. }")
  4205.  
  4206. (define_insn ""
  4207.   [(set (match_operand:SI 0 "general_operand" "=rm")
  4208.     (xor:SI (match_operand:SI 1 "general_operand" "0")
  4209.         (ashift:SI (const_int 1)
  4210.                (match_operand:SI 2 "general_operand" "r"))))]
  4211.   "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
  4212.   "*
  4213. {
  4214.   CC_STATUS_INIT;
  4215.  
  4216.   return AS2 (btc%L0,%2,%0);
  4217. }")
  4218.  
  4219. ;; Recognizers for bit-test instructions.
  4220.  
  4221. ;; The bt opcode allows a MEM in operands[0].  But on both i386 and
  4222. ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
  4223. ;; bt on the MEM directly.
  4224.  
  4225. ;; ??? The first argument of a zero_extract must not be reloaded, so
  4226. ;; don't allow a MEM in the operand predicate without allowing it in the
  4227. ;; constraint.
  4228.  
  4229. (define_insn ""
  4230.   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
  4231.                 (const_int 1)
  4232.                 (match_operand:SI 1 "general_operand" "r")))]
  4233.   "GET_CODE (operands[1]) != CONST_INT"
  4234.   "*
  4235. {
  4236.   cc_status.flags |= CC_Z_IN_NOT_C;
  4237.   return AS2 (bt%L0,%1,%0);
  4238. }")
  4239.  
  4240. (define_insn ""
  4241.   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
  4242.                 (match_operand:SI 1 "const_int_operand" "n")
  4243.                 (match_operand:SI 2 "const_int_operand" "n")))]
  4244.   ""
  4245.   "*
  4246. {
  4247.   unsigned int mask;
  4248.  
  4249.   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
  4250.   operands[1] = GEN_INT (mask);
  4251.  
  4252.   if (QI_REG_P (operands[0]))
  4253.     {
  4254.       if ((mask & ~0xff) == 0)
  4255.         {
  4256.       cc_status.flags |= CC_NOT_NEGATIVE;
  4257.       return AS2 (test%B0,%1,%b0);
  4258.     }
  4259.  
  4260.       if ((mask & ~0xff00) == 0)
  4261.         {
  4262.       cc_status.flags |= CC_NOT_NEGATIVE;
  4263.       operands[1] = GEN_INT (mask >> 8);
  4264.       return AS2 (test%B0,%1,%h0);
  4265.     }
  4266.     }
  4267.  
  4268.   return AS2 (test%L0,%1,%0);
  4269. }")
  4270.  
  4271. ;; ??? All bets are off if operand 0 is a volatile MEM reference.
  4272. ;; The CPU may access unspecified bytes around the actual target byte.
  4273.  
  4274. (define_insn ""
  4275.   [(set (cc0) (zero_extract (match_operand:QI 0 "general_operand" "rm")
  4276.                 (match_operand:SI 1 "const_int_operand" "n")
  4277.                 (match_operand:SI 2 "const_int_operand" "n")))]
  4278.   "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
  4279.   "*
  4280. {
  4281.   unsigned int mask;
  4282.  
  4283.   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
  4284.   operands[1] = GEN_INT (mask);
  4285.  
  4286.   if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
  4287.     {
  4288.       if ((mask & ~0xff) == 0)
  4289.         {
  4290.       cc_status.flags |= CC_NOT_NEGATIVE;
  4291.       return AS2 (test%B0,%1,%b0);
  4292.     }
  4293.  
  4294.       if ((mask & ~0xff00) == 0)
  4295.         {
  4296.       cc_status.flags |= CC_NOT_NEGATIVE;
  4297.       operands[1] = GEN_INT (mask >> 8);
  4298.  
  4299.       if (QI_REG_P (operands[0]))
  4300.         return AS2 (test%B0,%1,%h0);
  4301.       else
  4302.         {
  4303.           operands[0] = adj_offsettable_operand (operands[0], 1);
  4304.           return AS2 (test%B0,%1,%b0);
  4305.         }
  4306.     }
  4307.  
  4308.       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
  4309.         {
  4310.       cc_status.flags |= CC_NOT_NEGATIVE;
  4311.       operands[1] = GEN_INT (mask >> 16);
  4312.       operands[0] = adj_offsettable_operand (operands[0], 2);
  4313.       return AS2 (test%B0,%1,%b0);
  4314.     }
  4315.  
  4316.       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
  4317.         {
  4318.       cc_status.flags |= CC_NOT_NEGATIVE;
  4319.       operands[1] = GEN_INT (mask >> 24);
  4320.       operands[0] = adj_offsettable_operand (operands[0], 3);
  4321.       return AS2 (test%B0,%1,%b0);
  4322.     }
  4323.     }
  4324.  
  4325.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  4326.     return AS2 (test%L0,%1,%0);
  4327.  
  4328.   return AS2 (test%L1,%0,%1);
  4329. }")
  4330.  
  4331. ;; Store-flag instructions.
  4332.  
  4333. ;; For all sCOND expanders, also expand the compare or test insn that
  4334. ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
  4335.  
  4336. ;; The 386 sCOND opcodes can write to memory.  But a gcc sCOND insn may
  4337. ;; not have any input reloads.  A MEM write might need an input reload
  4338. ;; for the address of the MEM.  So don't allow MEM as the SET_DEST.
  4339.  
  4340. (define_expand "seq"
  4341.   [(match_dup 1)
  4342.    (set (match_operand:QI 0 "register_operand" "")
  4343.     (eq:QI (cc0) (const_int 0)))]
  4344.   ""
  4345.   "
  4346. {
  4347.   if (TARGET_IEEE_FP
  4348.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4349.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4350.   else
  4351.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4352. }")
  4353.  
  4354. (define_insn ""
  4355.   [(set (match_operand:QI 0 "register_operand" "=q")
  4356.     (eq:QI (cc0) (const_int 0)))]
  4357.   ""
  4358.   "*
  4359. {
  4360.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4361.     return AS1 (setnb,%0);
  4362.   else
  4363.     return AS1 (sete,%0);
  4364. }")
  4365.  
  4366. (define_expand "sne"
  4367.   [(match_dup 1)
  4368.    (set (match_operand:QI 0 "register_operand" "")
  4369.     (ne:QI (cc0) (const_int 0)))]
  4370.   ""
  4371.   "
  4372. {
  4373.   if (TARGET_IEEE_FP
  4374.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4375.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4376.   else
  4377.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4378. }")
  4379.  
  4380. (define_insn ""
  4381.   [(set (match_operand:QI 0 "register_operand" "=q")
  4382.     (ne:QI (cc0) (const_int 0)))]
  4383.   ""
  4384.   "*
  4385. {
  4386.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4387.     return AS1 (setb,%0);
  4388.   else
  4389.     return AS1 (setne,%0);
  4390. }
  4391. ")
  4392.  
  4393. (define_expand "sgt"
  4394.   [(match_dup 1)
  4395.    (set (match_operand:QI 0 "register_operand" "")
  4396.     (gt:QI (cc0) (const_int 0)))]
  4397.   ""
  4398.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4399.  
  4400. (define_insn ""
  4401.   [(set (match_operand:QI 0 "register_operand" "=q")
  4402.     (gt:QI (cc0) (const_int 0)))]
  4403.   ""
  4404.   "*
  4405. {
  4406.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4407.     return AS1 (sete,%0);
  4408.  
  4409.   OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
  4410. }")
  4411.  
  4412. (define_expand "sgtu"
  4413.   [(match_dup 1)
  4414.    (set (match_operand:QI 0 "register_operand" "")
  4415.     (gtu:QI (cc0) (const_int 0)))]
  4416.   ""
  4417.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4418.  
  4419. (define_insn ""
  4420.   [(set (match_operand:QI 0 "register_operand" "=q")
  4421.     (gtu:QI (cc0) (const_int 0)))]
  4422.   ""
  4423.   "* return \"seta %0\"; ")
  4424.  
  4425. (define_expand "slt"
  4426.   [(match_dup 1)
  4427.    (set (match_operand:QI 0 "register_operand" "")
  4428.     (lt:QI (cc0) (const_int 0)))]
  4429.   ""
  4430.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4431.  
  4432. (define_insn ""
  4433.   [(set (match_operand:QI 0 "register_operand" "=q")
  4434.     (lt:QI (cc0) (const_int 0)))]
  4435.   ""
  4436.   "*
  4437. {
  4438.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4439.     return AS1 (sete,%0);
  4440.  
  4441.   OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
  4442. }")
  4443.  
  4444. (define_expand "sltu"
  4445.   [(match_dup 1)
  4446.    (set (match_operand:QI 0 "register_operand" "")
  4447.     (ltu:QI (cc0) (const_int 0)))]
  4448.   ""
  4449.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4450.  
  4451. (define_insn ""
  4452.   [(set (match_operand:QI 0 "register_operand" "=q")
  4453.     (ltu:QI (cc0) (const_int 0)))]
  4454.   ""
  4455.   "* return \"setb %0\"; ")
  4456.  
  4457. (define_expand "sge"
  4458.   [(match_dup 1)
  4459.    (set (match_operand:QI 0 "register_operand" "")
  4460.     (ge:QI (cc0) (const_int 0)))]
  4461.   ""
  4462.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4463.  
  4464. (define_insn ""
  4465.   [(set (match_operand:QI 0 "register_operand" "=q")
  4466.     (ge:QI (cc0) (const_int 0)))]
  4467.   ""
  4468.   "*
  4469. {
  4470.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4471.     return AS1 (sete,%0);
  4472.  
  4473.   OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
  4474. }")
  4475.  
  4476. (define_expand "sgeu"
  4477.   [(match_dup 1)
  4478.    (set (match_operand:QI 0 "register_operand" "")
  4479.     (geu:QI (cc0) (const_int 0)))]
  4480.   ""
  4481.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4482.  
  4483. (define_insn ""
  4484.   [(set (match_operand:QI 0 "register_operand" "=q")
  4485.     (geu:QI (cc0) (const_int 0)))]
  4486.   ""
  4487.   "* return \"setae %0\"; ")
  4488.  
  4489. (define_expand "sle"
  4490.   [(match_dup 1)
  4491.    (set (match_operand:QI 0 "register_operand" "")
  4492.     (le:QI (cc0) (const_int 0)))]
  4493.   ""
  4494.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4495.  
  4496. (define_insn ""
  4497.   [(set (match_operand:QI 0 "register_operand" "=q")
  4498.     (le:QI (cc0) (const_int 0)))]
  4499.   ""
  4500.   "*
  4501. {
  4502.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4503.     return AS1 (setb,%0);
  4504.  
  4505.   OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
  4506. }")
  4507.  
  4508. (define_expand "sleu"
  4509.   [(match_dup 1)
  4510.    (set (match_operand:QI 0 "register_operand" "")
  4511.     (leu:QI (cc0) (const_int 0)))]
  4512.   ""
  4513.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4514.  
  4515. (define_insn ""
  4516.   [(set (match_operand:QI 0 "register_operand" "=q")
  4517.     (leu:QI (cc0) (const_int 0)))]
  4518.   ""
  4519.   "* return \"setbe %0\"; ")
  4520.  
  4521. ;; Basic conditional jump instructions.
  4522. ;; We ignore the overflow flag for signed branch instructions.
  4523.  
  4524. ;; For all bCOND expanders, also expand the compare or test insn that
  4525. ;; generates cc0.  Generate an equality comparison if `beq' or `bne'.
  4526.  
  4527. (define_expand "beq"
  4528.   [(match_dup 1)
  4529.    (set (pc)
  4530.     (if_then_else (eq (cc0)
  4531.               (const_int 0))
  4532.               (label_ref (match_operand 0 "" ""))
  4533.               (pc)))]
  4534.   ""
  4535.   "
  4536. {
  4537.   if (TARGET_IEEE_FP
  4538.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4539.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4540.   else
  4541.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4542. }")
  4543.  
  4544. (define_insn ""
  4545.   [(set (pc)
  4546.     (if_then_else (eq (cc0)
  4547.               (const_int 0))
  4548.               (label_ref (match_operand 0 "" ""))
  4549.               (pc)))]
  4550.   ""
  4551.   "*
  4552. {
  4553.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4554.     return \"jnc %l0\";
  4555.   else
  4556.     return \"je %l0\";
  4557. }")
  4558.  
  4559. (define_expand "bne"
  4560.   [(match_dup 1)
  4561.    (set (pc)
  4562.     (if_then_else (ne (cc0)
  4563.               (const_int 0))
  4564.               (label_ref (match_operand 0 "" ""))
  4565.               (pc)))]
  4566.   ""
  4567.   "
  4568. {
  4569.   if (TARGET_IEEE_FP
  4570.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4571.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4572.   else
  4573.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4574. }")
  4575.  
  4576. (define_insn ""
  4577.   [(set (pc)
  4578.     (if_then_else (ne (cc0)
  4579.               (const_int 0))
  4580.               (label_ref (match_operand 0 "" ""))
  4581.               (pc)))]
  4582.   ""
  4583.   "*
  4584. {
  4585.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4586.     return \"jc %l0\";
  4587.   else
  4588.     return \"jne %l0\";
  4589. }")
  4590.  
  4591. (define_expand "bgt"
  4592.   [(match_dup 1)
  4593.    (set (pc)
  4594.     (if_then_else (gt (cc0)
  4595.               (const_int 0))
  4596.               (label_ref (match_operand 0 "" ""))
  4597.               (pc)))]
  4598.   ""
  4599.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4600.  
  4601. (define_insn ""
  4602.   [(set (pc)
  4603.     (if_then_else (gt (cc0)
  4604.               (const_int 0))
  4605.               (label_ref (match_operand 0 "" ""))
  4606.               (pc)))]
  4607.   ""
  4608.   "*
  4609. {
  4610.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4611.     return AS1 (je,%l0);
  4612.  
  4613.   OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  4614. }")
  4615.  
  4616. (define_expand "bgtu"
  4617.   [(match_dup 1)
  4618.    (set (pc)
  4619.     (if_then_else (gtu (cc0)
  4620.                (const_int 0))
  4621.               (label_ref (match_operand 0 "" ""))
  4622.               (pc)))]
  4623.   ""
  4624.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4625.  
  4626. (define_insn ""
  4627.   [(set (pc)
  4628.     (if_then_else (gtu (cc0)
  4629.                (const_int 0))
  4630.               (label_ref (match_operand 0 "" ""))
  4631.               (pc)))]
  4632.   ""
  4633.   "ja %l0")
  4634.  
  4635. (define_expand "blt"
  4636.   [(match_dup 1)
  4637.    (set (pc)
  4638.     (if_then_else (lt (cc0)
  4639.               (const_int 0))
  4640.               (label_ref (match_operand 0 "" ""))
  4641.               (pc)))]
  4642.   ""
  4643.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4644.  
  4645. (define_insn ""
  4646.   [(set (pc)
  4647.     (if_then_else (lt (cc0)
  4648.               (const_int 0))
  4649.               (label_ref (match_operand 0 "" ""))
  4650.               (pc)))]
  4651.   ""
  4652.   "*
  4653. {
  4654.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4655.     return AS1 (je,%l0);
  4656.  
  4657.   OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  4658. }")
  4659.  
  4660. (define_expand "bltu"
  4661.   [(match_dup 1)
  4662.    (set (pc)
  4663.     (if_then_else (ltu (cc0)
  4664.                (const_int 0))
  4665.               (label_ref (match_operand 0 "" ""))
  4666.               (pc)))]
  4667.   ""
  4668.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4669.  
  4670. (define_insn ""
  4671.   [(set (pc)
  4672.     (if_then_else (ltu (cc0)
  4673.                (const_int 0))
  4674.               (label_ref (match_operand 0 "" ""))
  4675.               (pc)))]
  4676.   ""
  4677.   "jb %l0")
  4678.  
  4679. (define_expand "bge"
  4680.   [(match_dup 1)
  4681.    (set (pc)
  4682.     (if_then_else (ge (cc0)
  4683.               (const_int 0))
  4684.               (label_ref (match_operand 0 "" ""))
  4685.               (pc)))]
  4686.   ""
  4687.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4688.  
  4689. (define_insn ""
  4690.   [(set (pc)
  4691.     (if_then_else (ge (cc0)
  4692.               (const_int 0))
  4693.               (label_ref (match_operand 0 "" ""))
  4694.               (pc)))]
  4695.   ""
  4696.   "*
  4697. {
  4698.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4699.     return AS1 (je,%l0);
  4700.  
  4701.   OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  4702. }")
  4703.  
  4704. (define_expand "bgeu"
  4705.   [(match_dup 1)
  4706.    (set (pc)
  4707.     (if_then_else (geu (cc0)
  4708.                (const_int 0))
  4709.               (label_ref (match_operand 0 "" ""))
  4710.               (pc)))]
  4711.   ""
  4712.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4713.  
  4714. (define_insn ""
  4715.   [(set (pc)
  4716.     (if_then_else (geu (cc0)
  4717.                (const_int 0))
  4718.               (label_ref (match_operand 0 "" ""))
  4719.               (pc)))]
  4720.   ""
  4721.   "jae %l0")
  4722.  
  4723. (define_expand "ble"
  4724.   [(match_dup 1)
  4725.    (set (pc)
  4726.     (if_then_else (le (cc0)
  4727.               (const_int 0))
  4728.               (label_ref (match_operand 0 "" ""))
  4729.               (pc)))]
  4730.   ""
  4731.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4732.  
  4733. (define_insn ""
  4734.   [(set (pc)
  4735.     (if_then_else (le (cc0)
  4736.               (const_int 0))
  4737.               (label_ref (match_operand 0 "" ""))
  4738.               (pc)))]
  4739.   ""
  4740.   "*
  4741. {
  4742.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4743.     return AS1 (jb,%l0);
  4744.  
  4745.   OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  4746. }")
  4747.  
  4748. (define_expand "bleu"
  4749.   [(match_dup 1)
  4750.    (set (pc)
  4751.     (if_then_else (leu (cc0)
  4752.                (const_int 0))
  4753.               (label_ref (match_operand 0 "" ""))
  4754.               (pc)))]
  4755.   ""
  4756.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4757.  
  4758. (define_insn ""
  4759.   [(set (pc)
  4760.     (if_then_else (leu (cc0)
  4761.                (const_int 0))
  4762.               (label_ref (match_operand 0 "" ""))
  4763.               (pc)))]
  4764.   ""
  4765.   "jbe %l0")
  4766.  
  4767. ;; Negated conditional jump instructions.
  4768.  
  4769. (define_insn ""
  4770.   [(set (pc)
  4771.     (if_then_else (eq (cc0)
  4772.               (const_int 0))
  4773.               (pc)
  4774.               (label_ref (match_operand 0 "" ""))))]
  4775.   ""
  4776.   "*
  4777. {
  4778.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4779.     return \"jc %l0\";
  4780.   else
  4781.     return \"jne %l0\";
  4782. }")
  4783.  
  4784. (define_insn ""
  4785.   [(set (pc)
  4786.     (if_then_else (ne (cc0)
  4787.               (const_int 0))
  4788.               (pc)
  4789.               (label_ref (match_operand 0 "" ""))))]
  4790.   ""
  4791.   "*
  4792. {
  4793.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4794.     return \"jnc %l0\";
  4795.   else
  4796.     return \"je %l0\";
  4797. }")
  4798.  
  4799. (define_insn ""
  4800.   [(set (pc)
  4801.     (if_then_else (gt (cc0)
  4802.               (const_int 0))
  4803.               (pc)
  4804.               (label_ref (match_operand 0 "" ""))))]
  4805.   ""
  4806.   "*
  4807. {
  4808.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4809.     return AS1 (jne,%l0);
  4810.  
  4811.   OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  4812. }")
  4813.  
  4814. (define_insn ""
  4815.   [(set (pc)
  4816.     (if_then_else (gtu (cc0)
  4817.                (const_int 0))
  4818.               (pc)
  4819.               (label_ref (match_operand 0 "" ""))))]
  4820.   ""
  4821.   "jbe %l0")
  4822.  
  4823. (define_insn ""
  4824.   [(set (pc)
  4825.     (if_then_else (lt (cc0)
  4826.               (const_int 0))
  4827.               (pc)
  4828.               (label_ref (match_operand 0 "" ""))))]
  4829.   ""
  4830.   "*
  4831. {
  4832.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4833.     return AS1 (jne,%l0);
  4834.  
  4835.   OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  4836. }")
  4837.  
  4838. (define_insn ""
  4839.   [(set (pc)
  4840.     (if_then_else (ltu (cc0)
  4841.                (const_int 0))
  4842.               (pc)
  4843.               (label_ref (match_operand 0 "" ""))))]
  4844.   ""
  4845.   "jae %l0")
  4846.  
  4847. (define_insn ""
  4848.   [(set (pc)
  4849.     (if_then_else (ge (cc0)
  4850.               (const_int 0))
  4851.               (pc)
  4852.               (label_ref (match_operand 0 "" ""))))]
  4853.   ""
  4854.   "*
  4855. {
  4856.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4857.     return AS1 (jne,%l0);
  4858.  
  4859.   OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  4860. }")
  4861.  
  4862. (define_insn ""
  4863.   [(set (pc)
  4864.     (if_then_else (geu (cc0)
  4865.                (const_int 0))
  4866.               (pc)
  4867.               (label_ref (match_operand 0 "" ""))))]
  4868.   ""
  4869.   "jb %l0")
  4870.  
  4871. (define_insn ""
  4872.   [(set (pc)
  4873.     (if_then_else (le (cc0)
  4874.               (const_int 0))
  4875.               (pc)
  4876.               (label_ref (match_operand 0 "" ""))))]
  4877.   ""
  4878.   "*
  4879. {
  4880.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4881.     return AS1 (jae,%l0);
  4882.  
  4883.   OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  4884. }")
  4885.  
  4886. (define_insn ""
  4887.   [(set (pc)
  4888.     (if_then_else (leu (cc0)
  4889.                (const_int 0))
  4890.               (pc)
  4891.               (label_ref (match_operand 0 "" ""))))]
  4892.   ""
  4893.   "ja %l0")
  4894.  
  4895. ;; Unconditional and other jump instructions
  4896.  
  4897. (define_insn "jump"
  4898.   [(set (pc)
  4899.     (label_ref (match_operand 0 "" "")))]
  4900.   ""
  4901.   "jmp %l0")
  4902.  
  4903. (define_insn "indirect_jump"
  4904.   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
  4905.   ""
  4906.   "*
  4907. {
  4908.   CC_STATUS_INIT;
  4909.  
  4910.   return AS1 (jmp,%*%0);
  4911. }")
  4912.  
  4913. (define_expand "decrement_and_branch_until_zero"
  4914.   [(parallel [(set (pc)
  4915.            (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
  4916.                           (const_int -1))
  4917.                      (const_int 0))
  4918.                  (label_ref (match_operand 1 "" ""))
  4919.                  (pc)))
  4920.           (set (match_dup 0)
  4921.            (plus:SI (match_dup 0)
  4922.                 (const_int -1)))])]
  4923.   ""
  4924.   "")
  4925.  
  4926. (define_insn ""
  4927.   [(set (pc)
  4928.     (if_then_else (match_operator 0 "comparison_operator"
  4929.                       [(plus:SI (match_operand:SI 1 "general_operand" "+r,m")
  4930.                         (match_operand:SI 2 "general_operand" "rmi,ri"))
  4931.                        (const_int 0)])
  4932.               (label_ref (match_operand 3 "" ""))
  4933.               (pc)))
  4934.    (set (match_dup 1)
  4935.     (plus:SI (match_dup 1)
  4936.          (match_dup 2)))]
  4937.   ""
  4938.   "*
  4939. {
  4940.   CC_STATUS_INIT;
  4941.   if (operands[2] == constm1_rtx)
  4942.     output_asm_insn (AS1 (dec%L1,%1), operands);
  4943.  
  4944.   else if (operands[1] == const1_rtx)
  4945.     output_asm_insn (AS1 (inc%L1,%1), operands);
  4946.  
  4947.   else
  4948.     output_asm_insn (AS2 (add%L1,%2,%1), operands);
  4949.  
  4950.   return AS1 (%J0,%l3);
  4951. }")
  4952.  
  4953. (define_insn ""
  4954.   [(set (pc)
  4955.     (if_then_else (match_operator 0 "comparison_operator"
  4956.                       [(minus:SI (match_operand:SI 1 "general_operand" "+r,m")
  4957.                          (match_operand:SI 2 "general_operand" "rmi,ri"))
  4958.                        (const_int 0)])
  4959.               (label_ref (match_operand 3 "" ""))
  4960.               (pc)))
  4961.    (set (match_dup 1)
  4962.     (minus:SI (match_dup 1)
  4963.           (match_dup 2)))]
  4964.   ""
  4965.   "*
  4966. {
  4967.   CC_STATUS_INIT;
  4968.   if (operands[2] == const1_rtx)
  4969.     output_asm_insn (AS1 (dec%L1,%1), operands);
  4970.  
  4971.   else if (operands[1] == constm1_rtx)
  4972.     output_asm_insn (AS1 (inc%L1,%1), operands);
  4973.  
  4974.   else
  4975.     output_asm_insn (AS2 (sub%L1,%2,%1), operands);
  4976.  
  4977.   return AS1 (%J0,%l3);
  4978. }")
  4979.  
  4980. ;; Implement switch statements when generating PIC code.  Switches are
  4981. ;; implemented by `tablejump' when not using -fpic.
  4982.  
  4983. ;; Emit code here to do the range checking and make the index zero based.
  4984.  
  4985. (define_expand "casesi"
  4986.   [(set (match_dup 5)
  4987.     (minus:SI (match_operand:SI 0 "general_operand" "")
  4988.           (match_operand:SI 1 "general_operand" "")))
  4989.    (set (cc0)
  4990.     (compare:CC (match_dup 5)
  4991.             (match_operand:SI 2 "general_operand" "")))
  4992.    (set (pc)
  4993.     (if_then_else (gtu (cc0)
  4994.                (const_int 0))
  4995.               (label_ref (match_operand 4 "" ""))
  4996.               (pc)))
  4997.    (parallel
  4998.     [(set (pc)
  4999.       (minus:SI (reg:SI 3)
  5000.             (mem:SI (plus:SI (mult:SI (match_dup 5)
  5001.                           (const_int 4))
  5002.                      (label_ref (match_operand 3 "" ""))))))
  5003.      (clobber (match_scratch:SI 6 ""))])]
  5004.   "flag_pic"
  5005.   "
  5006. {
  5007.   operands[5] = gen_reg_rtx (SImode);
  5008.   current_function_uses_pic_offset_table = 1;
  5009. }")
  5010.  
  5011. ;; Implement a casesi insn.
  5012.  
  5013. ;; Each entry in the "addr_diff_vec" looks like this as the result of the
  5014. ;; two rules below:
  5015. ;; 
  5016. ;;     .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
  5017. ;; 
  5018. ;; 1. An expression involving an external reference may only use the
  5019. ;;    addition operator, and only with an assembly-time constant.
  5020. ;;    The example above satisfies this because ".-.L2" is a constant.
  5021. ;; 
  5022. ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
  5023. ;;    given the value of "GOT - .", where GOT is the actual address of
  5024. ;;    the Global Offset Table.  Therefore, the .long above actually
  5025. ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
  5026. ;;    expression "GOT - .L2" by itself would generate an error from as(1).
  5027. ;; 
  5028. ;; The pattern below emits code that looks like this:
  5029. ;; 
  5030. ;;     movl %ebx,reg
  5031. ;;     subl TABLE@GOTOFF(%ebx,index,4),reg
  5032. ;;     jmp reg
  5033. ;; 
  5034. ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
  5035. ;; the addr_diff_vec is known to be part of this module.
  5036. ;; 
  5037. ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
  5038. ;; evaluates to just ".L2".
  5039.  
  5040. (define_insn ""
  5041.   [(set (pc)
  5042.     (minus:SI (reg:SI 3)
  5043.           (mem:SI (plus:SI
  5044.                (mult:SI (match_operand:SI 0 "register_operand" "r")
  5045.                     (const_int 4))
  5046.                (label_ref (match_operand 1 "" ""))))))
  5047.    (clobber (match_scratch:SI 2 "=&r"))]
  5048.   ""
  5049.   "*
  5050. {
  5051.   rtx xops[4];
  5052.  
  5053.   xops[0] = operands[0];
  5054.   xops[1] = operands[1];
  5055.   xops[2] = operands[2];
  5056.   xops[3] = pic_offset_table_rtx;
  5057.  
  5058.   output_asm_insn (AS2 (mov%L2,%3,%2), xops);
  5059.   output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
  5060.   output_asm_insn (AS1 (jmp,%*%2), xops);
  5061.   ASM_OUTPUT_ALIGN_CODE (asm_out_file);
  5062.   RET;
  5063. }")
  5064.  
  5065. (define_insn "tablejump"
  5066.   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
  5067.    (use (label_ref (match_operand 1 "" "")))]
  5068.   ""
  5069.   "*
  5070. {
  5071.   CC_STATUS_INIT;
  5072.  
  5073.   return AS1 (jmp,%*%0);
  5074. }")
  5075.  
  5076. ;; Call insns.
  5077.  
  5078. ;; If generating PIC code, the predicate indirect_operand will fail
  5079. ;; for operands[0] containing symbolic references on all of the named
  5080. ;; call* patterns.  Each named pattern is followed by an unnamed pattern
  5081. ;; that matches any call to a symbolic CONST (ie, a symbol_ref).  The
  5082. ;; unnamed patterns are only used while generating PIC code, because
  5083. ;; otherwise the named patterns match.
  5084.  
  5085. ;; Call subroutine returning no value.
  5086.  
  5087. (define_expand "call_pop"
  5088.   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
  5089.             (match_operand:SI 1 "general_operand" ""))
  5090.           (set (reg:SI 7)
  5091.            (plus:SI (reg:SI 7)
  5092.                 (match_operand:SI 3 "immediate_operand" "")))])]
  5093.   ""
  5094.   "
  5095. {
  5096.   rtx addr;
  5097.  
  5098.   if (flag_pic)
  5099.     current_function_uses_pic_offset_table = 1;
  5100.  
  5101.   /* With half-pic, force the address into a register.  */
  5102.   addr = XEXP (operands[0], 0);
  5103.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  5104.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  5105.  
  5106.   if (! expander_call_insn_operand (operands[0], QImode))
  5107.     operands[0]
  5108.       = change_address (operands[0], VOIDmode,
  5109.             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  5110. }")
  5111.  
  5112. (define_insn ""
  5113.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  5114.      (match_operand:SI 1 "general_operand" "g"))
  5115.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  5116.                 (match_operand:SI 3 "immediate_operand" "i")))]
  5117.   ""
  5118.   "*
  5119. {
  5120.   if (GET_CODE (operands[0]) == MEM
  5121.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  5122.     {
  5123.       operands[0] = XEXP (operands[0], 0);
  5124.       return AS1 (call,%*%0);
  5125.     }
  5126.   else
  5127.     return AS1 (call,%P0);
  5128. }")
  5129.  
  5130. (define_insn ""
  5131.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  5132.      (match_operand:SI 1 "general_operand" "g"))
  5133.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  5134.                 (match_operand:SI 3 "immediate_operand" "i")))]
  5135.   "!HALF_PIC_P ()"
  5136.   "call %P0")
  5137.  
  5138. (define_expand "call"
  5139.   [(call (match_operand:QI 0 "indirect_operand" "")
  5140.      (match_operand:SI 1 "general_operand" ""))]
  5141.   ;; Operand 1 not used on the i386.
  5142.   ""
  5143.   "
  5144. {
  5145.   rtx addr;
  5146.  
  5147.   if (flag_pic)
  5148.     current_function_uses_pic_offset_table = 1;
  5149.  
  5150.   /* With half-pic, force the address into a register.  */
  5151.   addr = XEXP (operands[0], 0);
  5152.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  5153.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  5154.  
  5155.   if (! expander_call_insn_operand (operands[0], QImode))
  5156.     operands[0]
  5157.       = change_address (operands[0], VOIDmode,
  5158.             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  5159. }")
  5160.  
  5161. (define_insn ""
  5162.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  5163.      (match_operand:SI 1 "general_operand" "g"))]
  5164.   ;; Operand 1 not used on the i386.
  5165.   ""
  5166.   "*
  5167. {
  5168.   if (GET_CODE (operands[0]) == MEM
  5169.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  5170.     {
  5171.       operands[0] = XEXP (operands[0], 0);
  5172.       return AS1 (call,%*%0);
  5173.     }
  5174.   else
  5175.     return AS1 (call,%P0);
  5176. }")
  5177.  
  5178. (define_insn ""
  5179.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  5180.      (match_operand:SI 1 "general_operand" "g"))]
  5181.   ;; Operand 1 not used on the i386.
  5182.   "!HALF_PIC_P ()"
  5183.   "call %P0")
  5184.  
  5185. ;; Call subroutine, returning value in operand 0
  5186. ;; (which must be a hard register).
  5187.  
  5188. (define_expand "call_value_pop"
  5189.   [(parallel [(set (match_operand 0 "" "")
  5190.            (call (match_operand:QI 1 "indirect_operand" "")
  5191.              (match_operand:SI 2 "general_operand" "")))
  5192.           (set (reg:SI 7)
  5193.            (plus:SI (reg:SI 7)
  5194.                 (match_operand:SI 4 "immediate_operand" "")))])]
  5195.   ""
  5196.   "
  5197. {
  5198.   rtx addr;
  5199.  
  5200.   if (flag_pic)
  5201.     current_function_uses_pic_offset_table = 1;
  5202.  
  5203.   /* With half-pic, force the address into a register.  */
  5204.   addr = XEXP (operands[1], 0);
  5205.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  5206.     XEXP (operands[1], 0) = force_reg (Pmode, addr);
  5207.  
  5208.   if (! expander_call_insn_operand (operands[1], QImode))
  5209.     operands[1]
  5210.       = change_address (operands[1], VOIDmode,
  5211.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  5212. }")
  5213.  
  5214. (define_insn ""
  5215.   [(set (match_operand 0 "" "=rf")
  5216.     (call (match_operand:QI 1 "call_insn_operand" "m")
  5217.           (match_operand:SI 2 "general_operand" "g")))
  5218.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  5219.                 (match_operand:SI 4 "immediate_operand" "i")))]
  5220.   ""
  5221.   "*
  5222. {
  5223.   if (GET_CODE (operands[1]) == MEM
  5224.       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  5225.     {
  5226.       operands[1] = XEXP (operands[1], 0);
  5227.       output_asm_insn (AS1 (call,%*%1), operands);
  5228.     }
  5229.   else
  5230.     output_asm_insn (AS1 (call,%P1), operands);
  5231.  
  5232.   RET;
  5233. }")
  5234.  
  5235. (define_insn ""
  5236.   [(set (match_operand 0 "" "=rf")
  5237.     (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
  5238.           (match_operand:SI 2 "general_operand" "g")))
  5239.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  5240.                 (match_operand:SI 4 "immediate_operand" "i")))]
  5241.   "!HALF_PIC_P ()"
  5242.   "call %P1")
  5243.  
  5244. (define_expand "call_value"
  5245.   [(set (match_operand 0 "" "")
  5246.     (call (match_operand:QI 1 "indirect_operand" "")
  5247.           (match_operand:SI 2 "general_operand" "")))]
  5248.   ;; Operand 2 not used on the i386.
  5249.   ""
  5250.   "
  5251. {
  5252.   rtx addr;
  5253.  
  5254.   if (flag_pic)
  5255.     current_function_uses_pic_offset_table = 1;
  5256.  
  5257.   /* With half-pic, force the address into a register.  */
  5258.   addr = XEXP (operands[1], 0);
  5259.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  5260.     XEXP (operands[1], 0) = force_reg (Pmode, addr);
  5261.  
  5262.   if (! expander_call_insn_operand (operands[1], QImode))
  5263.     operands[1]
  5264.       = change_address (operands[1], VOIDmode,
  5265.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  5266. }")
  5267.  
  5268. (define_insn ""
  5269.   [(set (match_operand 0 "" "=rf")
  5270.     (call (match_operand:QI 1 "call_insn_operand" "m")
  5271.           (match_operand:SI 2 "general_operand" "g")))]
  5272.   ;; Operand 2 not used on the i386.
  5273.   ""
  5274.   "*
  5275. {
  5276.   if (GET_CODE (operands[1]) == MEM
  5277.       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  5278.     {
  5279.       operands[1] = XEXP (operands[1], 0);
  5280.       output_asm_insn (AS1 (call,%*%1), operands);
  5281.     }
  5282.   else
  5283.     output_asm_insn (AS1 (call,%P1), operands);
  5284.  
  5285.   RET;
  5286. }")
  5287.  
  5288. (define_insn ""
  5289.   [(set (match_operand 0 "" "=rf")
  5290.     (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
  5291.           (match_operand:SI 2 "general_operand" "g")))]
  5292.   ;; Operand 2 not used on the i386.
  5293.   "!HALF_PIC_P ()"
  5294.   "call %P1")
  5295.  
  5296. ;; Call subroutine returning any type.
  5297.  
  5298. (define_expand "untyped_call"
  5299.   [(parallel [(call (match_operand 0 "" "")
  5300.             (const_int 0))
  5301.           (match_operand 1 "" "")
  5302.           (match_operand 2 "" "")])]
  5303.   ""
  5304.   "
  5305. {
  5306.   int i;
  5307.  
  5308.   /* In order to give reg-stack an easier job in validating two
  5309.      coprocessor registers as containing a possible return value,
  5310.      simply pretend the untyped call returns a complex long double
  5311.      value.  */
  5312.   emit_call_insn (TARGET_80387
  5313.                   ? gen_call_value (gen_rtx (REG, XCmode, FIRST_FLOAT_REG),
  5314.                           operands[0], const0_rtx)
  5315.                   : gen_call (operands[0], const0_rtx));
  5316.  
  5317.   for (i = 0; i < XVECLEN (operands[2], 0); i++)
  5318.     {
  5319.       rtx set = XVECEXP (operands[2], 0, i);
  5320.       emit_move_insn (SET_DEST (set), SET_SRC (set));
  5321.     }
  5322.  
  5323.   /* The optimizer does not know that the call sets the function value
  5324.      registers we stored in the result block.  We avoid problems by
  5325.      claiming that all hard registers are used and clobbered at this
  5326.      point.  */
  5327.   emit_insn (gen_blockage ());
  5328.  
  5329.   DONE;
  5330. }")
  5331.  
  5332. ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
  5333. ;; all of memory.  This blocks insns from being moved across this point.
  5334.  
  5335. (define_insn "blockage"
  5336.   [(unspec_volatile [(const_int 0)] 0)]
  5337.   ""
  5338.   "")
  5339.  
  5340. ;; Insn emitted into the body of a function to return from a function.
  5341. ;; This is only done if the function's epilogue is known to be simple.
  5342. ;; See comments for simple_386_epilogue in i386.c.
  5343.  
  5344. (define_insn "return"
  5345.   [(return)]
  5346.   "simple_386_epilogue ()"
  5347.   "*
  5348. {
  5349.   function_epilogue (asm_out_file, get_frame_size ());
  5350.   RET;
  5351. }")
  5352.  
  5353. (define_insn "nop"
  5354.   [(const_int 0)]
  5355.   ""
  5356.   "nop")
  5357.  
  5358. (define_expand "movstrsi"
  5359.   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
  5360.            (match_operand:BLK 1 "memory_operand" ""))
  5361.           (use (match_operand:SI 2 "const_int_operand" ""))
  5362.           (use (match_operand:SI 3 "const_int_operand" ""))
  5363.           (clobber (match_scratch:SI 4 ""))
  5364.           (clobber (match_dup 5))
  5365.           (clobber (match_dup 6))])]
  5366.   ""
  5367.   "
  5368. {
  5369.   rtx addr0, addr1;
  5370.  
  5371.   if (GET_CODE (operands[2]) != CONST_INT)
  5372.     FAIL;
  5373.  
  5374.   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
  5375.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  5376.  
  5377.   operands[5] = addr0;
  5378.   operands[6] = addr1;
  5379.  
  5380.   operands[0] = gen_rtx (MEM, BLKmode, addr0);
  5381.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  5382. }")
  5383.  
  5384. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5385. ;; But strength reduction might offset the MEM expression.  So we let
  5386. ;; reload put the address into %edi & %esi.
  5387.  
  5388. (define_insn ""
  5389.   [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
  5390.     (mem:BLK (match_operand:SI 1 "address_operand" "S")))
  5391.    (use (match_operand:SI 2 "const_int_operand" "n"))
  5392.    (use (match_operand:SI 3 "immediate_operand" "i"))
  5393.    (clobber (match_scratch:SI 4 "=&c"))
  5394.    (clobber (match_dup 0))
  5395.    (clobber (match_dup 1))]
  5396.   ""
  5397.   "*
  5398. {
  5399.   rtx xops[2];
  5400.  
  5401.   output_asm_insn (\"cld\", operands);
  5402.   if (GET_CODE (operands[2]) == CONST_INT)
  5403.     {
  5404.       if (INTVAL (operands[2]) & ~0x03)
  5405.     {
  5406.       xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
  5407.       xops[1] = operands[4];
  5408.  
  5409.       output_asm_insn (AS2 (mov%L1,%0,%1), xops);
  5410. #ifdef INTEL_SYNTAX
  5411.       output_asm_insn (\"rep movsd\", xops);
  5412. #else
  5413.       output_asm_insn (\"rep\;movsl\", xops);
  5414. #endif
  5415.     }
  5416.       if (INTVAL (operands[2]) & 0x02)
  5417.     output_asm_insn (\"movsw\", operands);
  5418.       if (INTVAL (operands[2]) & 0x01)
  5419.     output_asm_insn (\"movsb\", operands);
  5420.     }
  5421.   else
  5422.     abort ();
  5423.   RET;
  5424. }")
  5425.  
  5426. (define_expand "cmpstrsi"
  5427.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  5428.            (compare:SI (match_operand:BLK 1 "general_operand" "")
  5429.                    (match_operand:BLK 2 "general_operand" "")))
  5430.           (use (match_operand:SI 3 "general_operand" ""))
  5431.           (use (match_operand:SI 4 "immediate_operand" ""))
  5432.           (clobber (match_dup 5))
  5433.           (clobber (match_dup 6))
  5434.           (clobber (match_dup 3))])]
  5435.   ""
  5436.   "
  5437. {
  5438.   rtx addr1, addr2;
  5439.  
  5440.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  5441.   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
  5442.   operands[3] = copy_to_mode_reg (SImode, operands[3]);
  5443.  
  5444.   operands[5] = addr1;
  5445.   operands[6] = addr2;
  5446.  
  5447.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  5448.   operands[2] = gen_rtx (MEM, BLKmode, addr2);
  5449.  
  5450. }")
  5451.  
  5452. ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
  5453. ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
  5454.  
  5455. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5456. ;; But strength reduction might offset the MEM expression.  So we let
  5457. ;; reload put the address into %edi & %esi.
  5458.  
  5459. ;; ??? Most comparisons have a constant length, and it's therefore
  5460. ;; possible to know that the length is non-zero, and to avoid the extra
  5461. ;; code to handle zero-length compares.
  5462.  
  5463. (define_insn ""
  5464.   [(set (match_operand:SI 0 "general_operand" "=&r")
  5465.     (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
  5466.             (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
  5467.    (use (match_operand:SI 3 "register_operand" "c"))
  5468.    (use (match_operand:SI 4 "immediate_operand" "i"))
  5469.    (clobber (match_dup 1))
  5470.    (clobber (match_dup 2))
  5471.    (clobber (match_dup 3))]
  5472.   ""
  5473.   "*
  5474. {
  5475.   rtx xops[4], label;
  5476.  
  5477.   label = gen_label_rtx ();
  5478.  
  5479.   output_asm_insn (\"cld\", operands);
  5480.   output_asm_insn (AS2 (xor%L0,%0,%0), operands);
  5481.   output_asm_insn (\"repz\;cmps%B2\", operands);
  5482.   output_asm_insn (\"je %l0\", &label);
  5483.  
  5484.   xops[0] = operands[0];
  5485.   xops[1] = gen_rtx (MEM, QImode,
  5486.              gen_rtx (PLUS, SImode, operands[1], constm1_rtx));
  5487.   xops[2] = gen_rtx (MEM, QImode,
  5488.              gen_rtx (PLUS, SImode, operands[2], constm1_rtx));
  5489.   xops[3] = operands[3];
  5490.  
  5491.   output_asm_insn (AS2 (movz%B1%L0,%1,%0), xops);
  5492.   output_asm_insn (AS2 (movz%B2%L3,%2,%3), xops);
  5493.  
  5494.   output_asm_insn (AS2 (sub%L0,%3,%0), xops);
  5495.   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
  5496.   RET;
  5497. }")
  5498.  
  5499. (define_insn ""
  5500.   [(set (cc0)
  5501.     (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
  5502.             (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
  5503.    (use (match_operand:SI 2 "register_operand" "c"))
  5504.    (use (match_operand:SI 3 "immediate_operand" "i"))
  5505.    (clobber (match_dup 0))
  5506.    (clobber (match_dup 1))
  5507.    (clobber (match_dup 2))]
  5508.   ""
  5509.   "*
  5510. {
  5511.   rtx xops[2];
  5512.  
  5513.   cc_status.flags |= CC_NOT_SIGNED;
  5514.  
  5515.   xops[0] = gen_rtx (REG, QImode, 0);
  5516.   xops[1] = CONST0_RTX (QImode);
  5517.  
  5518.   output_asm_insn (\"cld\", operands);
  5519.   output_asm_insn (AS2 (test%B0,%1,%0), xops);
  5520.   return \"repz\;cmps%B2\";
  5521. }")
  5522.  
  5523. (define_expand "ffssi2"
  5524.   [(set (match_dup 2)
  5525.     (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
  5526.          (const_int -1)))
  5527.    (set (match_operand:SI 0 "general_operand" "")
  5528.     (plus:SI (match_dup 2) (const_int 1)))]
  5529.   ""
  5530.   "operands[2] = gen_reg_rtx (SImode);")
  5531.  
  5532. ;; Note, you cannot optimize away the branch following the bsfl by assuming
  5533. ;; that the destination is not modified if the input is 0, since not all
  5534. ;; x86 implementations do this.
  5535.  
  5536. (define_insn ""
  5537.   [(set (match_operand:SI 0 "general_operand" "=&r")
  5538.     (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm"))
  5539.          (const_int -1)))]
  5540.   ""
  5541.   "*
  5542. {
  5543.   rtx xops[3];
  5544.   static int ffssi_label_number;
  5545.   char buffer[30];
  5546.  
  5547.   xops[0] = operands[0];
  5548.   xops[1] = operands[1];
  5549.   xops[2] = constm1_rtx;
  5550.   output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
  5551. #ifdef LOCAL_LABEL_PREFIX
  5552.   sprintf (buffer, \"jnz %sLFFSSI%d\",
  5553.        LOCAL_LABEL_PREFIX, ffssi_label_number);
  5554. #else
  5555.   sprintf (buffer, \"jnz %sLFFSSI%d\",
  5556.        \"\", ffssi_label_number);
  5557. #endif
  5558.   output_asm_insn (buffer, xops);
  5559.   output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  5560. #ifdef LOCAL_LABEL_PREFIX
  5561.   sprintf (buffer, \"%sLFFSSI%d:\",
  5562.        LOCAL_LABEL_PREFIX, ffssi_label_number);
  5563. #else
  5564.   sprintf (buffer, \"%sLFFSSI%d:\",
  5565.        \"\", ffssi_label_number);
  5566. #endif
  5567.   output_asm_insn (buffer, xops);
  5568.  
  5569.   ffssi_label_number++;
  5570.   return \"\";
  5571. }")
  5572.  
  5573. (define_expand "ffshi2"
  5574.   [(set (match_dup 2)
  5575.     (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" ""))
  5576.          (const_int -1)))
  5577.    (set (match_operand:HI 0 "general_operand" "")
  5578.     (plus:HI (match_dup 2) (const_int 1)))]
  5579.   ""
  5580.   "operands[2] = gen_reg_rtx (HImode);")
  5581.  
  5582. (define_insn ""
  5583.   [(set (match_operand:HI 0 "general_operand" "=&r")
  5584.     (plus:HI (ffs:HI (match_operand:SI 1 "general_operand" "rm"))
  5585.          (const_int -1)))]
  5586.   ""
  5587.   "*
  5588. {
  5589.   rtx xops[3];
  5590.   static int ffshi_label_number;
  5591.   char buffer[30];
  5592.  
  5593.   xops[0] = operands[0];
  5594.   xops[1] = operands[1];
  5595.   xops[2] = constm1_rtx;
  5596.   output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
  5597. #ifdef LOCAL_LABEL_PREFIX
  5598.   sprintf (buffer, \"jnz %sLFFSHI%d\",
  5599.        LOCAL_LABEL_PREFIX, ffshi_label_number);
  5600. #else
  5601.   sprintf (buffer, \"jnz %sLFFSHI%d\",
  5602.        \"\", ffshi_label_number);
  5603. #endif
  5604.   output_asm_insn (buffer, xops);
  5605.   output_asm_insn (AS2 (mov%W0,%2,%0), xops);
  5606. #ifdef LOCAL_LABEL_PREFIX
  5607.   sprintf (buffer, \"%sLFFSHI%d:\",
  5608.        LOCAL_LABEL_PREFIX, ffshi_label_number);
  5609. #else
  5610.   sprintf (buffer, \"%sLFFSHI%d:\",
  5611.        \"\", ffshi_label_number);
  5612. #endif
  5613.   output_asm_insn (buffer, xops);
  5614.  
  5615.   ffshi_label_number++;
  5616.   return \"\";
  5617. }")
  5618.  
  5619. ;; These patterns match the binary 387 instructions for addM3, subM3,
  5620. ;; mulM3 and divM3.  There are three patterns for each of DFmode and
  5621. ;; SFmode.  The first is the normal insn, the second the same insn but
  5622. ;; with one operand a conversion, and the third the same insn but with
  5623. ;; the other operand a conversion.  The conversion may be SFmode or
  5624. ;; SImode if the target mode DFmode, but only SImode if the target mode
  5625. ;; is SFmode.
  5626.  
  5627. (define_insn ""
  5628.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5629.     (match_operator:DF 3 "binary_387_op"
  5630.             [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
  5631.              (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
  5632.   "TARGET_80387"
  5633.   "* return output_387_binary_op (insn, operands);")
  5634.  
  5635. (define_insn ""
  5636.   [(set (match_operand:DF 0 "register_operand" "=f")
  5637.     (match_operator:DF 3 "binary_387_op"
  5638.        [(float:DF (match_operand:SI 1 "general_operand" "rm"))
  5639.         (match_operand:DF 2 "general_operand" "0")]))]
  5640.   "TARGET_80387"
  5641.   "* return output_387_binary_op (insn, operands);")
  5642.  
  5643. (define_insn ""
  5644.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5645.     (match_operator:XF 3 "binary_387_op"
  5646.             [(match_operand:XF 1 "nonimmediate_operand" "0,f")
  5647.              (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
  5648.   "TARGET_80387"
  5649.   "* return output_387_binary_op (insn, operands);")
  5650.  
  5651. (define_insn ""
  5652.   [(set (match_operand:XF 0 "register_operand" "=f")
  5653.     (match_operator:XF 3 "binary_387_op"
  5654.        [(float:XF (match_operand:SI 1 "general_operand" "rm"))
  5655.         (match_operand:XF 2 "general_operand" "0")]))]
  5656.   "TARGET_80387"
  5657.   "* return output_387_binary_op (insn, operands);")
  5658.  
  5659. (define_insn ""
  5660.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5661.     (match_operator:XF 3 "binary_387_op"
  5662.        [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
  5663.         (match_operand:XF 2 "general_operand" "0,f")]))]
  5664.   "TARGET_80387"
  5665.   "* return output_387_binary_op (insn, operands);")
  5666.  
  5667. (define_insn ""
  5668.   [(set (match_operand:XF 0 "register_operand" "=f")
  5669.     (match_operator:XF 3 "binary_387_op"
  5670.       [(match_operand:XF 1 "general_operand" "0")
  5671.        (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
  5672.   "TARGET_80387"
  5673.   "* return output_387_binary_op (insn, operands);")
  5674.  
  5675. (define_insn ""
  5676.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5677.     (match_operator:XF 3 "binary_387_op"
  5678.       [(match_operand:XF 1 "general_operand" "0,f")
  5679.        (float_extend:XF
  5680.         (match_operand:SF 2 "general_operand" "fm,0"))]))]
  5681.   "TARGET_80387"
  5682.   "* return output_387_binary_op (insn, operands);")
  5683.  
  5684. (define_insn ""
  5685.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5686.     (match_operator:DF 3 "binary_387_op"
  5687.        [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
  5688.         (match_operand:DF 2 "general_operand" "0,f")]))]
  5689.   "TARGET_80387"
  5690.   "* return output_387_binary_op (insn, operands);")
  5691.  
  5692. (define_insn ""
  5693.   [(set (match_operand:DF 0 "register_operand" "=f")
  5694.     (match_operator:DF 3 "binary_387_op"
  5695.       [(match_operand:DF 1 "general_operand" "0")
  5696.        (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
  5697.   "TARGET_80387"
  5698.   "* return output_387_binary_op (insn, operands);")
  5699.  
  5700. (define_insn ""
  5701.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5702.     (match_operator:DF 3 "binary_387_op"
  5703.       [(match_operand:DF 1 "general_operand" "0,f")
  5704.        (float_extend:DF
  5705.         (match_operand:SF 2 "general_operand" "fm,0"))]))]
  5706.   "TARGET_80387"
  5707.   "* return output_387_binary_op (insn, operands);")
  5708.  
  5709. (define_insn ""
  5710.   [(set (match_operand:SF 0 "register_operand" "=f,f")
  5711.     (match_operator:SF 3 "binary_387_op"
  5712.             [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
  5713.              (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
  5714.   "TARGET_80387"
  5715.   "* return output_387_binary_op (insn, operands);")
  5716.  
  5717. (define_insn ""
  5718.   [(set (match_operand:SF 0 "register_operand" "=f")
  5719.     (match_operator:SF 3 "binary_387_op"
  5720.       [(float:SF (match_operand:SI 1 "general_operand" "rm"))
  5721.        (match_operand:SF 2 "general_operand" "0")]))]
  5722.   "TARGET_80387"
  5723.   "* return output_387_binary_op (insn, operands);")
  5724.  
  5725. (define_insn ""
  5726.   [(set (match_operand:SF 0 "register_operand" "=f")
  5727.     (match_operator:SF 3 "binary_387_op"
  5728.       [(match_operand:SF 1 "general_operand" "0")
  5729.        (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
  5730.   "TARGET_80387"
  5731.   "* return output_387_binary_op (insn, operands);")
  5732.  
  5733. (define_expand "strlensi"
  5734.   [(parallel [(set (match_dup 4)
  5735.            (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
  5736.                    (match_operand:QI 2 "register_operand" "")
  5737.                    (match_operand:SI 3 "immediate_operand" "")] 0))
  5738.           (clobber (match_dup 1))])
  5739.    (set (match_dup 5)
  5740.     (not:SI (match_dup 4)))
  5741.    (set (match_operand:SI 0 "register_operand" "")
  5742.     (minus:SI (match_dup 5)
  5743.          (const_int 1)))]
  5744.   ""
  5745.   "
  5746. {
  5747.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  5748.   operands[4] = gen_reg_rtx (SImode);
  5749.   operands[5] = gen_reg_rtx (SImode);
  5750. }")
  5751.  
  5752. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5753. ;; But strength reduction might offset the MEM expression.  So we let
  5754. ;; reload put the address into %edi.
  5755.  
  5756. (define_insn ""
  5757.   [(set (match_operand:SI 0 "register_operand" "=&c")
  5758.     (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
  5759.             (match_operand:QI 2 "register_operand" "a")
  5760.             (match_operand:SI 3 "immediate_operand" "i")] 0))
  5761.    (clobber (match_dup 1))]
  5762.   ""
  5763.   "*
  5764. {
  5765.   rtx xops[2];
  5766.  
  5767.   xops[0] = operands[0];
  5768.   xops[1] = constm1_rtx;
  5769.   output_asm_insn (\"cld\", operands);
  5770.   output_asm_insn (AS2 (mov%L0,%1,%0), xops);
  5771.   return \"repnz\;scas%B2\";
  5772. }")
  5773.